Issues (4967)

Security Analysis    not enabled

This project does not seem to handle request data directly as such no vulnerable execution paths were found.

  Cross-Site Scripting
Cross-Site Scripting enables an attacker to inject code into the response of a web-request that is viewed by other users. It can for example be used to bypass access controls, or even to take over other users' accounts.
  File Exposure
File Exposure allows an attacker to gain access to local files that he should not be able to access. These files can for example include database credentials, or other configuration files.
  File Manipulation
File Manipulation enables an attacker to write custom data to files. This potentially leads to injection of arbitrary code on the server.
  Object Injection
Object Injection enables an attacker to inject an object into PHP code, and can lead to arbitrary code execution, file exposure, or file manipulation attacks.
  Code Injection
Code Injection enables an attacker to execute arbitrary code on the server.
  Response Splitting
Response Splitting can be used to send arbitrary responses.
  File Inclusion
File Inclusion enables an attacker to inject custom files into PHP's file loading mechanism, either explicitly passed to include, or for example via PHP's auto-loading mechanism.
  Command Injection
Command Injection enables an attacker to inject a shell command that is execute with the privileges of the web-server. This can be used to expose sensitive data, or gain access of your server.
  SQL Injection
SQL Injection enables an attacker to execute arbitrary SQL code on your database server gaining access to user data, or manipulating user data.
  XPath Injection
XPath Injection enables an attacker to modify the parts of XML document that are read. If that XML document is for example used for authentication, this can lead to further vulnerabilities similar to SQL Injection.
  LDAP Injection
LDAP Injection enables an attacker to inject LDAP statements potentially granting permission to run unauthorized queries, or modify content inside the LDAP tree.
  Header Injection
  Other Vulnerability
This category comprises other attack vectors such as manipulating the PHP runtime, loading custom extensions, freezing the runtime, or similar.
  Regex Injection
Regex Injection enables an attacker to execute arbitrary code in your PHP process.
  XML Injection
XML Injection enables an attacker to read files on your local filesystem including configuration files, or can be abused to freeze your web-server process.
  Variable Injection
Variable Injection enables an attacker to overwrite program variables with custom data, and can lead to further vulnerabilities.
Unfortunately, the security analysis is currently not available for your project. If you are a non-commercial open-source project, please contact support to gain access.

src/wp-includes/general-template.php (21 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
/**
3
 * General template tags that can go anywhere in a template.
4
 *
5
 * @package WordPress
6
 * @subpackage Template
7
 */
8
9
/**
10
 * Load header template.
11
 *
12
 * Includes the header template for a theme or if a name is specified then a
13
 * specialised header will be included.
14
 *
15
 * For the parameter, if the file is called "header-special.php" then specify
16
 * "special".
17
 *
18
 * @since 1.5.0
19
 *
20
 * @param string $name The name of the specialised header.
21
 */
22 View Code Duplication
function get_header( $name = null ) {
0 ignored issues
show
This function seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
23
	/**
24
	 * Fires before the header template file is loaded.
25
	 *
26
	 * The hook allows a specific header template file to be used in place of the
27
	 * default header template file. If your file is called header-new.php,
28
	 * you would specify the filename in the hook as get_header( 'new' ).
29
	 *
30
	 * @since 2.1.0
31
	 * @since 2.8.0 $name parameter added.
32
	 *
33
	 * @param string|null $name Name of the specific header file to use. null for the default header.
34
	 */
35
	do_action( 'get_header', $name );
36
37
	$templates = array();
38
	$name = (string) $name;
39
	if ( '' !== $name ) {
40
		$templates[] = "header-{$name}.php";
41
	}
42
43
	$templates[] = 'header.php';
44
45
	locate_template( $templates, true );
46
}
47
48
/**
49
 * Load footer template.
50
 *
51
 * Includes the footer template for a theme or if a name is specified then a
52
 * specialised footer will be included.
53
 *
54
 * For the parameter, if the file is called "footer-special.php" then specify
55
 * "special".
56
 *
57
 * @since 1.5.0
58
 *
59
 * @param string $name The name of the specialised footer.
60
 */
61 View Code Duplication
function get_footer( $name = null ) {
0 ignored issues
show
This function seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
62
	/**
63
	 * Fires before the footer template file is loaded.
64
	 *
65
	 * The hook allows a specific footer template file to be used in place of the
66
	 * default footer template file. If your file is called footer-new.php,
67
	 * you would specify the filename in the hook as get_footer( 'new' ).
68
	 *
69
	 * @since 2.1.0
70
	 * @since 2.8.0 $name parameter added.
71
	 *
72
	 * @param string|null $name Name of the specific footer file to use. null for the default footer.
73
	 */
74
	do_action( 'get_footer', $name );
75
76
	$templates = array();
77
	$name = (string) $name;
78
	if ( '' !== $name ) {
79
		$templates[] = "footer-{$name}.php";
80
	}
81
82
	$templates[]    = 'footer.php';
83
84
	locate_template( $templates, true );
85
}
86
87
/**
88
 * Load sidebar template.
89
 *
90
 * Includes the sidebar template for a theme or if a name is specified then a
91
 * specialised sidebar will be included.
92
 *
93
 * For the parameter, if the file is called "sidebar-special.php" then specify
94
 * "special".
95
 *
96
 * @since 1.5.0
97
 *
98
 * @param string $name The name of the specialised sidebar.
99
 */
100 View Code Duplication
function get_sidebar( $name = null ) {
0 ignored issues
show
This function seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
101
	/**
102
	 * Fires before the sidebar template file is loaded.
103
	 *
104
	 * The hook allows a specific sidebar template file to be used in place of the
105
	 * default sidebar template file. If your file is called sidebar-new.php,
106
	 * you would specify the filename in the hook as get_sidebar( 'new' ).
107
	 *
108
	 * @since 2.2.0
109
	 * @since 2.8.0 $name parameter added.
110
	 *
111
	 * @param string|null $name Name of the specific sidebar file to use. null for the default sidebar.
112
	 */
113
	do_action( 'get_sidebar', $name );
114
115
	$templates = array();
116
	$name = (string) $name;
117
	if ( '' !== $name )
118
		$templates[] = "sidebar-{$name}.php";
119
120
	$templates[] = 'sidebar.php';
121
122
	locate_template( $templates, true );
123
}
124
125
/**
126
 * Load a template part into a template
127
 *
128
 * Makes it easy for a theme to reuse sections of code in a easy to overload way
129
 * for child themes.
130
 *
131
 * Includes the named template part for a theme or if a name is specified then a
132
 * specialised part will be included. If the theme contains no {slug}.php file
133
 * then no template will be included.
134
 *
135
 * The template is included using require, not require_once, so you may include the
136
 * same template part multiple times.
137
 *
138
 * For the $name parameter, if the file is called "{slug}-special.php" then specify
139
 * "special".
140
 *
141
 * @since 3.0.0
142
 *
143
 * @param string $slug The slug name for the generic template.
144
 * @param string $name The name of the specialised template.
145
 */
146
function get_template_part( $slug, $name = null ) {
147
	/**
148
	 * Fires before the specified template part file is loaded.
149
	 *
150
	 * The dynamic portion of the hook name, `$slug`, refers to the slug name
151
	 * for the generic template part.
152
	 *
153
	 * @since 3.0.0
154
	 *
155
	 * @param string      $slug The slug name for the generic template.
156
	 * @param string|null $name The name of the specialized template.
157
	 */
158
	do_action( "get_template_part_{$slug}", $slug, $name );
159
160
	$templates = array();
161
	$name = (string) $name;
162
	if ( '' !== $name )
163
		$templates[] = "{$slug}-{$name}.php";
164
165
	$templates[] = "{$slug}.php";
166
167
	locate_template($templates, true, false);
168
}
169
170
/**
171
 * Display search form.
172
 *
173
 * Will first attempt to locate the searchform.php file in either the child or
174
 * the parent, then load it. If it doesn't exist, then the default search form
175
 * will be displayed. The default search form is HTML, which will be displayed.
176
 * There is a filter applied to the search form HTML in order to edit or replace
177
 * it. The filter is {@see 'get_search_form'}.
178
 *
179
 * This function is primarily used by themes which want to hardcode the search
180
 * form into the sidebar and also by the search widget in WordPress.
181
 *
182
 * There is also an action that is called whenever the function is run called,
183
 * {@see 'pre_get_search_form'}. This can be useful for outputting JavaScript that the
184
 * search relies on or various formatting that applies to the beginning of the
185
 * search. To give a few examples of what it can be used for.
186
 *
187
 * @since 2.7.0
188
 *
189
 * @param bool $echo Default to echo and not return the form.
190
 * @return string|void String when $echo is false.
191
 */
192
function get_search_form( $echo = true ) {
193
	/**
194
	 * Fires before the search form is retrieved, at the start of get_search_form().
195
	 *
196
	 * @since 2.7.0 as 'get_search_form' action.
197
	 * @since 3.6.0
198
	 *
199
	 * @link https://core.trac.wordpress.org/ticket/19321
200
	 */
201
	do_action( 'pre_get_search_form' );
202
203
	$format = current_theme_supports( 'html5', 'search-form' ) ? 'html5' : 'xhtml';
204
205
	/**
206
	 * Filters the HTML format of the search form.
207
	 *
208
	 * @since 3.6.0
209
	 *
210
	 * @param string $format The type of markup to use in the search form.
211
	 *                       Accepts 'html5', 'xhtml'.
212
	 */
213
	$format = apply_filters( 'search_form_format', $format );
214
215
	$search_form_template = locate_template( 'searchform.php' );
216
	if ( '' != $search_form_template ) {
217
		ob_start();
218
		require( $search_form_template );
219
		$form = ob_get_clean();
220
	} else {
221
		if ( 'html5' == $format ) {
222
			$form = '<form role="search" method="get" class="search-form" action="' . esc_url( home_url( '/' ) ) . '">
223
				<label>
224
					<span class="screen-reader-text">' . _x( 'Search for:', 'label' ) . '</span>
225
					<input type="search" class="search-field" placeholder="' . esc_attr_x( 'Search &hellip;', 'placeholder' ) . '" value="' . get_search_query() . '" name="s" />
226
				</label>
227
				<input type="submit" class="search-submit" value="'. esc_attr_x( 'Search', 'submit button' ) .'" />
228
			</form>';
229
		} else {
230
			$form = '<form role="search" method="get" id="searchform" class="searchform" action="' . esc_url( home_url( '/' ) ) . '">
231
				<div>
232
					<label class="screen-reader-text" for="s">' . _x( 'Search for:', 'label' ) . '</label>
233
					<input type="text" value="' . get_search_query() . '" name="s" id="s" />
234
					<input type="submit" id="searchsubmit" value="'. esc_attr_x( 'Search', 'submit button' ) .'" />
235
				</div>
236
			</form>';
237
		}
238
	}
239
240
	/**
241
	 * Filters the HTML output of the search form.
242
	 *
243
	 * @since 2.7.0
244
	 *
245
	 * @param string $form The search form HTML output.
246
	 */
247
	$result = apply_filters( 'get_search_form', $form );
248
249
	if ( null === $result )
250
		$result = $form;
251
252
	if ( $echo )
253
		echo $result;
254
	else
255
		return $result;
256
}
257
258
/**
259
 * Display the Log In/Out link.
260
 *
261
 * Displays a link, which allows users to navigate to the Log In page to log in
262
 * or log out depending on whether they are currently logged in.
263
 *
264
 * @since 1.5.0
265
 *
266
 * @param string $redirect Optional path to redirect to on login/logout.
267
 * @param bool   $echo     Default to echo and not return the link.
268
 * @return string|void String when retrieving.
269
 */
270
function wp_loginout($redirect = '', $echo = true) {
271
	if ( ! is_user_logged_in() )
272
		$link = '<a href="' . esc_url( wp_login_url($redirect) ) . '">' . __('Log in') . '</a>';
273
	else
274
		$link = '<a href="' . esc_url( wp_logout_url($redirect) ) . '">' . __('Log out') . '</a>';
275
276
	if ( $echo ) {
277
		/**
278
		 * Filters the HTML output for the Log In/Log Out link.
279
		 *
280
		 * @since 1.5.0
281
		 *
282
		 * @param string $link The HTML link content.
283
		 */
284
		echo apply_filters( 'loginout', $link );
285
	} else {
286
		/** This filter is documented in wp-includes/general-template.php */
287
		return apply_filters( 'loginout', $link );
288
	}
289
}
290
291
/**
292
 * Retrieves the logout URL.
293
 *
294
 * Returns the URL that allows the user to log out of the site.
295
 *
296
 * @since 2.7.0
297
 *
298
 * @param string $redirect Path to redirect to on logout.
299
 * @return string The logout URL. Note: HTML-encoded via esc_html() in wp_nonce_url().
300
 */
301 View Code Duplication
function wp_logout_url($redirect = '') {
0 ignored issues
show
This function seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
302
	$args = array( 'action' => 'logout' );
303
	if ( !empty($redirect) ) {
304
		$args['redirect_to'] = urlencode( $redirect );
305
	}
306
307
	$logout_url = add_query_arg($args, site_url('wp-login.php', 'login'));
308
	$logout_url = wp_nonce_url( $logout_url, 'log-out' );
309
310
	/**
311
	 * Filters the logout URL.
312
	 *
313
	 * @since 2.8.0
314
	 *
315
	 * @param string $logout_url The HTML-encoded logout URL.
316
	 * @param string $redirect   Path to redirect to on logout.
317
	 */
318
	return apply_filters( 'logout_url', $logout_url, $redirect );
319
}
320
321
/**
322
 * Retrieves the login URL.
323
 *
324
 * @since 2.7.0
325
 *
326
 * @param string $redirect     Path to redirect to on log in.
327
 * @param bool   $force_reauth Whether to force reauthorization, even if a cookie is present.
328
 *                             Default false.
329
 * @return string The login URL. Not HTML-encoded.
330
 */
331 View Code Duplication
function wp_login_url($redirect = '', $force_reauth = false) {
0 ignored issues
show
This function seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
332
	$login_url = site_url('wp-login.php', 'login');
333
334
	if ( !empty($redirect) )
335
		$login_url = add_query_arg('redirect_to', urlencode($redirect), $login_url);
336
337
	if ( $force_reauth )
338
		$login_url = add_query_arg('reauth', '1', $login_url);
339
340
	/**
341
	 * Filters the login URL.
342
	 *
343
	 * @since 2.8.0
344
	 * @since 4.2.0 The `$force_reauth` parameter was added.
345
	 *
346
	 * @param string $login_url    The login URL. Not HTML-encoded.
347
	 * @param string $redirect     The path to redirect to on login, if supplied.
348
	 * @param bool   $force_reauth Whether to force reauthorization, even if a cookie is present.
349
	 */
350
	return apply_filters( 'login_url', $login_url, $redirect, $force_reauth );
351
}
352
353
/**
354
 * Returns the URL that allows the user to register on the site.
355
 *
356
 * @since 3.6.0
357
 *
358
 * @return string User registration URL.
359
 */
360
function wp_registration_url() {
361
	/**
362
	 * Filters the user registration URL.
363
	 *
364
	 * @since 3.6.0
365
	 *
366
	 * @param string $register The user registration URL.
367
	 */
368
	return apply_filters( 'register_url', site_url( 'wp-login.php?action=register', 'login' ) );
369
}
370
371
/**
372
 * Provides a simple login form for use anywhere within WordPress.
373
 *
374
 * The login format HTML is echoed by default. Pass a false value for `$echo` to return it instead.
375
 *
376
 * @since 3.0.0
377
 *
378
 * @param array $args {
379
 *     Optional. Array of options to control the form output. Default empty array.
380
 *
381
 *     @type bool   $echo           Whether to display the login form or return the form HTML code.
382
 *                                  Default true (echo).
383
 *     @type string $redirect       URL to redirect to. Must be absolute, as in "https://example.com/mypage/".
384
 *                                  Default is to redirect back to the request URI.
385
 *     @type string $form_id        ID attribute value for the form. Default 'loginform'.
386
 *     @type string $label_username Label for the username or email address field. Default 'Username or Email Address'.
387
 *     @type string $label_password Label for the password field. Default 'Password'.
388
 *     @type string $label_remember Label for the remember field. Default 'Remember Me'.
389
 *     @type string $label_log_in   Label for the submit button. Default 'Log In'.
390
 *     @type string $id_username    ID attribute value for the username field. Default 'user_login'.
391
 *     @type string $id_password    ID attribute value for the password field. Default 'user_pass'.
392
 *     @type string $id_remember    ID attribute value for the remember field. Default 'rememberme'.
393
 *     @type string $id_submit      ID attribute value for the submit button. Default 'wp-submit'.
394
 *     @type bool   $remember       Whether to display the "rememberme" checkbox in the form.
395
 *     @type string $value_username Default value for the username field. Default empty.
396
 *     @type bool   $value_remember Whether the "Remember Me" checkbox should be checked by default.
397
 *                                  Default false (unchecked).
398
 *
399
 * }
400
 * @return string|void String when retrieving.
401
 */
402
function wp_login_form( $args = array() ) {
403
	$defaults = array(
404
		'echo' => true,
405
		// Default 'redirect' value takes the user back to the request URI.
406
		'redirect' => ( is_ssl() ? 'https://' : 'http://' ) . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'],
407
		'form_id' => 'loginform',
408
		'label_username' => __( 'Username or Email Address' ),
409
		'label_password' => __( 'Password' ),
410
		'label_remember' => __( 'Remember Me' ),
411
		'label_log_in' => __( 'Log In' ),
412
		'id_username' => 'user_login',
413
		'id_password' => 'user_pass',
414
		'id_remember' => 'rememberme',
415
		'id_submit' => 'wp-submit',
416
		'remember' => true,
417
		'value_username' => '',
418
		// Set 'value_remember' to true to default the "Remember me" checkbox to checked.
419
		'value_remember' => false,
420
	);
421
422
	/**
423
	 * Filters the default login form output arguments.
424
	 *
425
	 * @since 3.0.0
426
	 *
427
	 * @see wp_login_form()
428
	 *
429
	 * @param array $defaults An array of default login form arguments.
430
	 */
431
	$args = wp_parse_args( $args, apply_filters( 'login_form_defaults', $defaults ) );
432
433
	/**
434
	 * Filters content to display at the top of the login form.
435
	 *
436
	 * The filter evaluates just following the opening form tag element.
437
	 *
438
	 * @since 3.0.0
439
	 *
440
	 * @param string $content Content to display. Default empty.
441
	 * @param array  $args    Array of login form arguments.
442
	 */
443
	$login_form_top = apply_filters( 'login_form_top', '', $args );
444
445
	/**
446
	 * Filters content to display in the middle of the login form.
447
	 *
448
	 * The filter evaluates just following the location where the 'login-password'
449
	 * field is displayed.
450
	 *
451
	 * @since 3.0.0
452
	 *
453
	 * @param string $content Content to display. Default empty.
454
	 * @param array  $args    Array of login form arguments.
455
	 */
456
	$login_form_middle = apply_filters( 'login_form_middle', '', $args );
457
458
	/**
459
	 * Filters content to display at the bottom of the login form.
460
	 *
461
	 * The filter evaluates just preceding the closing form tag element.
462
	 *
463
	 * @since 3.0.0
464
	 *
465
	 * @param string $content Content to display. Default empty.
466
	 * @param array  $args    Array of login form arguments.
467
	 */
468
	$login_form_bottom = apply_filters( 'login_form_bottom', '', $args );
469
470
	$form = '
471
		<form name="' . $args['form_id'] . '" id="' . $args['form_id'] . '" action="' . esc_url( site_url( 'wp-login.php', 'login_post' ) ) . '" method="post">
472
			' . $login_form_top . '
473
			<p class="login-username">
474
				<label for="' . esc_attr( $args['id_username'] ) . '">' . esc_html( $args['label_username'] ) . '</label>
475
				<input type="text" name="log" id="' . esc_attr( $args['id_username'] ) . '" class="input" value="' . esc_attr( $args['value_username'] ) . '" size="20" />
476
			</p>
477
			<p class="login-password">
478
				<label for="' . esc_attr( $args['id_password'] ) . '">' . esc_html( $args['label_password'] ) . '</label>
479
				<input type="password" name="pwd" id="' . esc_attr( $args['id_password'] ) . '" class="input" value="" size="20" />
480
			</p>
481
			' . $login_form_middle . '
482
			' . ( $args['remember'] ? '<p class="login-remember"><label><input name="rememberme" type="checkbox" id="' . esc_attr( $args['id_remember'] ) . '" value="forever"' . ( $args['value_remember'] ? ' checked="checked"' : '' ) . ' /> ' . esc_html( $args['label_remember'] ) . '</label></p>' : '' ) . '
483
			<p class="login-submit">
484
				<input type="submit" name="wp-submit" id="' . esc_attr( $args['id_submit'] ) . '" class="button button-primary" value="' . esc_attr( $args['label_log_in'] ) . '" />
485
				<input type="hidden" name="redirect_to" value="' . esc_url( $args['redirect'] ) . '" />
486
			</p>
487
			' . $login_form_bottom . '
488
		</form>';
489
490
	if ( $args['echo'] )
491
		echo $form;
492
	else
493
		return $form;
494
}
495
496
/**
497
 * Returns the URL that allows the user to retrieve the lost password
498
 *
499
 * @since 2.8.0
500
 *
501
 * @param string $redirect Path to redirect to on login.
502
 * @return string Lost password URL.
503
 */
504
function wp_lostpassword_url( $redirect = '' ) {
505
	$args = array( 'action' => 'lostpassword' );
506
	if ( !empty($redirect) ) {
507
		$args['redirect_to'] = $redirect;
508
	}
509
510
	$lostpassword_url = add_query_arg( $args, network_site_url('wp-login.php', 'login') );
511
512
	/**
513
	 * Filters the Lost Password URL.
514
	 *
515
	 * @since 2.8.0
516
	 *
517
	 * @param string $lostpassword_url The lost password page URL.
518
	 * @param string $redirect         The path to redirect to on login.
519
	 */
520
	return apply_filters( 'lostpassword_url', $lostpassword_url, $redirect );
521
}
522
523
/**
524
 * Display the Registration or Admin link.
525
 *
526
 * Display a link which allows the user to navigate to the registration page if
527
 * not logged in and registration is enabled or to the dashboard if logged in.
528
 *
529
 * @since 1.5.0
530
 *
531
 * @param string $before Text to output before the link. Default `<li>`.
532
 * @param string $after  Text to output after the link. Default `</li>`.
533
 * @param bool   $echo   Default to echo and not return the link.
534
 * @return string|void String when retrieving.
535
 */
536
function wp_register( $before = '<li>', $after = '</li>', $echo = true ) {
537
	if ( ! is_user_logged_in() ) {
538
		if ( get_option('users_can_register') )
539
			$link = $before . '<a href="' . esc_url( wp_registration_url() ) . '">' . __('Register') . '</a>' . $after;
540
		else
541
			$link = '';
542
	} elseif ( current_user_can( 'read' ) ) {
543
		$link = $before . '<a href="' . admin_url() . '">' . __('Site Admin') . '</a>' . $after;
544
	} else {
545
		$link = '';
546
	}
547
548
	/**
549
	 * Filters the HTML link to the Registration or Admin page.
550
	 *
551
	 * Users are sent to the admin page if logged-in, or the registration page
552
	 * if enabled and logged-out.
553
	 *
554
	 * @since 1.5.0
555
	 *
556
	 * @param string $link The HTML code for the link to the Registration or Admin page.
557
	 */
558
	$link = apply_filters( 'register', $link );
559
560
	if ( $echo ) {
561
		echo $link;
562
	} else {
563
		return $link;
564
	}
565
}
566
567
/**
568
 * Theme container function for the 'wp_meta' action.
569
 *
570
 * The {@see 'wp_meta'} action can have several purposes, depending on how you use it,
571
 * but one purpose might have been to allow for theme switching.
572
 *
573
 * @since 1.5.0
574
 *
575
 * @link https://core.trac.wordpress.org/ticket/1458 Explanation of 'wp_meta' action.
576
 */
577
function wp_meta() {
578
	/**
579
	 * Fires before displaying echoed content in the sidebar.
580
	 *
581
	 * @since 1.5.0
582
	 */
583
	do_action( 'wp_meta' );
584
}
585
586
/**
587
 * Displays information about the current site.
588
 *
589
 * @since 0.71
590
 *
591
 * @see get_bloginfo() For possible `$show` values
592
 *
593
 * @param string $show Optional. Site information to display. Default empty.
594
 */
595
function bloginfo( $show = '' ) {
596
	echo get_bloginfo( $show, 'display' );
597
}
598
599
/**
600
 * Retrieves information about the current site.
601
 *
602
 * Possible values for `$show` include:
603
 *
604
 * - 'name' - Site title (set in Settings > General)
605
 * - 'description' - Site tagline (set in Settings > General)
606
 * - 'wpurl' - The WordPress address (URL) (set in Settings > General)
607
 * - 'url' - The Site address (URL) (set in Settings > General)
608
 * - 'admin_email' - Admin email (set in Settings > General)
609
 * - 'charset' - The "Encoding for pages and feeds"  (set in Settings > Reading)
610
 * - 'version' - The current WordPress version
611
 * - 'html_type' - The content-type (default: "text/html"). Themes and plugins
612
 *   can override the default value using the {@see 'pre_option_html_type'} filter
613
 * - 'text_direction' - The text direction determined by the site's language. is_rtl()
614
 *   should be used instead
615
 * - 'language' - Language code for the current site
616
 * - 'stylesheet_url' - URL to the stylesheet for the active theme. An active child theme
617
 *   will take precedence over this value
618
 * - 'stylesheet_directory' - Directory path for the active theme.  An active child theme
619
 *   will take precedence over this value
620
 * - 'template_url' / 'template_directory' - URL of the active theme's directory. An active
621
 *   child theme will NOT take precedence over this value
622
 * - 'pingback_url' - The pingback XML-RPC file URL (xmlrpc.php)
623
 * - 'atom_url' - The Atom feed URL (/feed/atom)
624
 * - 'rdf_url' - The RDF/RSS 1.0 feed URL (/feed/rfd)
625
 * - 'rss_url' - The RSS 0.92 feed URL (/feed/rss)
626
 * - 'rss2_url' - The RSS 2.0 feed URL (/feed)
627
 * - 'comments_atom_url' - The comments Atom feed URL (/comments/feed)
628
 * - 'comments_rss2_url' - The comments RSS 2.0 feed URL (/comments/feed)
629
 *
630
 * Some `$show` values are deprecated and will be removed in future versions.
631
 * These options will trigger the _deprecated_argument() function.
632
 *
633
 * Deprecated arguments include:
634
 *
635
 * - 'siteurl' - Use 'url' instead
636
 * - 'home' - Use 'url' instead
637
 *
638
 * @since 0.71
639
 *
640
 * @global string $wp_version
641
 *
642
 * @param string $show   Optional. Site info to retrieve. Default empty (site name).
643
 * @param string $filter Optional. How to filter what is retrieved. Default 'raw'.
644
 * @return string Mostly string values, might be empty.
645
 */
646
function get_bloginfo( $show = '', $filter = 'raw' ) {
647
	switch( $show ) {
648
		case 'home' : // DEPRECATED
649
		case 'siteurl' : // DEPRECATED
650
			_deprecated_argument( __FUNCTION__, '2.2.0', sprintf(
651
				/* translators: 1: 'siteurl'/'home' argument, 2: bloginfo() function name, 3: 'url' argument */
652
				__( 'The %1$s option is deprecated for the family of %2$s functions. Use the %3$s option instead.' ),
653
				'<code>' . $show . '</code>',
654
				'<code>bloginfo()</code>',
655
				'<code>url</code>'
656
			) );
657
		case 'url' :
658
			$output = home_url();
659
			break;
660
		case 'wpurl' :
661
			$output = site_url();
662
			break;
663
		case 'description':
664
			$output = get_option('blogdescription');
665
			break;
666
		case 'rdf_url':
667
			$output = get_feed_link('rdf');
668
			break;
669
		case 'rss_url':
670
			$output = get_feed_link('rss');
671
			break;
672
		case 'rss2_url':
673
			$output = get_feed_link('rss2');
674
			break;
675
		case 'atom_url':
676
			$output = get_feed_link('atom');
677
			break;
678
		case 'comments_atom_url':
679
			$output = get_feed_link('comments_atom');
680
			break;
681
		case 'comments_rss2_url':
682
			$output = get_feed_link('comments_rss2');
683
			break;
684
		case 'pingback_url':
685
			$output = site_url( 'xmlrpc.php' );
686
			break;
687
		case 'stylesheet_url':
688
			$output = get_stylesheet_uri();
689
			break;
690
		case 'stylesheet_directory':
691
			$output = get_stylesheet_directory_uri();
692
			break;
693
		case 'template_directory':
694
		case 'template_url':
695
			$output = get_template_directory_uri();
696
			break;
697
		case 'admin_email':
698
			$output = get_option('admin_email');
699
			break;
700
		case 'charset':
701
			$output = get_option('blog_charset');
702
			if ('' == $output) $output = 'UTF-8';
703
			break;
704
		case 'html_type' :
705
			$output = get_option('html_type');
706
			break;
707
		case 'version':
708
			global $wp_version;
709
			$output = $wp_version;
710
			break;
711
		case 'language':
712
			/* translators: Translate this to the correct language tag for your locale,
713
			 * see https://www.w3.org/International/articles/language-tags/ for reference.
714
			 * Do not translate into your own language.
715
			 */
716
			$output = __( 'html_lang_attribute' );
717
			if ( 'html_lang_attribute' === $output || preg_match( '/[^a-zA-Z0-9-]/', $output ) ) {
718
				$output = get_locale();
719
				$output = str_replace( '_', '-', $output );
720
			}
721
			break;
722
		case 'text_direction':
723
			_deprecated_argument( __FUNCTION__, '2.2.0', sprintf(
724
				/* translators: 1: 'text_direction' argument, 2: bloginfo() function name, 3: is_rtl() function name */
725
				__( 'The %1$s option is deprecated for the family of %2$s functions. Use the %3$s function instead.' ),
726
				'<code>' . $show . '</code>',
727
				'<code>bloginfo()</code>',
728
				'<code>is_rtl()</code>'
729
			) );
730
			if ( function_exists( 'is_rtl' ) ) {
731
				$output = is_rtl() ? 'rtl' : 'ltr';
732
			} else {
733
				$output = 'ltr';
734
			}
735
			break;
736
		case 'name':
737
		default:
738
			$output = get_option('blogname');
739
			break;
740
	}
741
742
	$url = true;
743
	if (strpos($show, 'url') === false &&
744
		strpos($show, 'directory') === false &&
745
		strpos($show, 'home') === false)
746
		$url = false;
747
748
	if ( 'display' == $filter ) {
749
		if ( $url ) {
750
			/**
751
			 * Filters the URL returned by get_bloginfo().
752
			 *
753
			 * @since 2.0.5
754
			 *
755
			 * @param mixed $output The URL returned by bloginfo().
756
			 * @param mixed $show   Type of information requested.
757
			 */
758
			$output = apply_filters( 'bloginfo_url', $output, $show );
759
		} else {
760
			/**
761
			 * Filters the site information returned by get_bloginfo().
762
			 *
763
			 * @since 0.71
764
			 *
765
			 * @param mixed $output The requested non-URL site information.
766
			 * @param mixed $show   Type of information requested.
767
			 */
768
			$output = apply_filters( 'bloginfo', $output, $show );
769
		}
770
	}
771
772
	return $output;
773
}
774
775
/**
776
 * Returns the Site Icon URL.
777
 *
778
 * @since 4.3.0
779
 *
780
 * @param int    $size    Optional. Size of the site icon. Default 512 (pixels).
781
 * @param string $url     Optional. Fallback url if no site icon is found. Default empty.
782
 * @param int    $blog_id Optional. ID of the blog to get the site icon for. Default current blog.
783
 * @return string Site Icon URL.
784
 */
785
function get_site_icon_url( $size = 512, $url = '', $blog_id = 0 ) {
786
	$switched_blog = false;
787
788 View Code Duplication
	if ( is_multisite() && ! empty( $blog_id ) && (int) $blog_id !== get_current_blog_id() ) {
789
		switch_to_blog( $blog_id );
790
		$switched_blog = true;
791
	}
792
793
	$site_icon_id = get_option( 'site_icon' );
794
795
	if ( $site_icon_id ) {
796
		if ( $size >= 512 ) {
797
			$size_data = 'full';
798
		} else {
799
			$size_data = array( $size, $size );
800
		}
801
		$url = wp_get_attachment_image_url( $site_icon_id, $size_data );
802
	}
803
804
	if ( $switched_blog ) {
805
		restore_current_blog();
806
	}
807
808
	/**
809
	 * Filters the site icon URL.
810
	 *
811
	 * @since 4.4.0
812
	 *
813
	 * @param string $url     Site icon URL.
814
	 * @param int    $size    Size of the site icon.
815
	 * @param int    $blog_id ID of the blog to get the site icon for.
816
	 */
817
	return apply_filters( 'get_site_icon_url', $url, $size, $blog_id );
818
}
819
820
/**
821
 * Displays the Site Icon URL.
822
 *
823
 * @since 4.3.0
824
 *
825
 * @param int    $size    Optional. Size of the site icon. Default 512 (pixels).
826
 * @param string $url     Optional. Fallback url if no site icon is found. Default empty.
827
 * @param int    $blog_id Optional. ID of the blog to get the site icon for. Default current blog.
828
 */
829
function site_icon_url( $size = 512, $url = '', $blog_id = 0 ) {
830
	echo esc_url( get_site_icon_url( $size, $url, $blog_id ) );
831
}
832
833
/**
834
 * Whether the site has a Site Icon.
835
 *
836
 * @since 4.3.0
837
 *
838
 * @param int $blog_id Optional. ID of the blog in question. Default current blog.
839
 * @return bool Whether the site has a site icon or not.
840
 */
841
function has_site_icon( $blog_id = 0 ) {
842
	return (bool) get_site_icon_url( 512, '', $blog_id );
843
}
844
845
/**
846
 * Determines whether the site has a custom logo.
847
 *
848
 * @since 4.5.0
849
 *
850
 * @param int $blog_id Optional. ID of the blog in question. Default is the ID of the current blog.
851
 * @return bool Whether the site has a custom logo or not.
852
 */
853
function has_custom_logo( $blog_id = 0 ) {
854
	$switched_blog = false;
855
856 View Code Duplication
	if ( is_multisite() && ! empty( $blog_id ) && (int) $blog_id !== get_current_blog_id() ) {
857
		switch_to_blog( $blog_id );
858
		$switched_blog = true;
859
	}
860
861
	$custom_logo_id = get_theme_mod( 'custom_logo' );
862
863
	if ( $switched_blog ) {
864
		restore_current_blog();
865
	}
866
867
	return (bool) $custom_logo_id;
868
}
869
870
/**
871
 * Returns a custom logo, linked to home.
872
 *
873
 * @since 4.5.0
874
 *
875
 * @param int $blog_id Optional. ID of the blog in question. Default is the ID of the current blog.
876
 * @return string Custom logo markup.
877
 */
878
function get_custom_logo( $blog_id = 0 ) {
879
	$html = '';
880
	$switched_blog = false;
881
882 View Code Duplication
	if ( is_multisite() && ! empty( $blog_id ) && (int) $blog_id !== get_current_blog_id() ) {
883
		switch_to_blog( $blog_id );
884
		$switched_blog = true;
885
	}
886
887
	$custom_logo_id = get_theme_mod( 'custom_logo' );
888
889
	// We have a logo. Logo is go.
890
	if ( $custom_logo_id ) {
891
		$custom_logo_attr = array(
892
			'class'    => 'custom-logo',
893
			'itemprop' => 'logo',
894
		);
895
896
		/*
897
		 * If the logo alt attribute is empty, get the site title and explicitly
898
		 * pass it to the attributes used by wp_get_attachment_image().
899
		 */
900
		$image_alt = get_post_meta( $custom_logo_id, '_wp_attachment_image_alt', true );
901
		if ( empty( $image_alt ) ) {
902
			$custom_logo_attr['alt'] = get_bloginfo( 'name', 'display' );
903
		}
904
905
		/*
906
		 * If the alt attribute is not empty, there's no need to explicitly pass
907
		 * it because wp_get_attachment_image() already adds the alt attribute.
908
		 */
909
		$html = sprintf( '<a href="%1$s" class="custom-logo-link" rel="home" itemprop="url">%2$s</a>',
910
			esc_url( home_url( '/' ) ),
911
			wp_get_attachment_image( $custom_logo_id, 'full', false, $custom_logo_attr )
912
		);
913
	}
914
915
	// If no logo is set but we're in the Customizer, leave a placeholder (needed for the live preview).
916
	elseif ( is_customize_preview() ) {
917
		$html = sprintf( '<a href="%1$s" class="custom-logo-link" style="display:none;"><img class="custom-logo"/></a>',
918
			esc_url( home_url( '/' ) )
919
		);
920
	}
921
922
	if ( $switched_blog ) {
923
		restore_current_blog();
924
	}
925
926
	/**
927
	 * Filters the custom logo output.
928
	 *
929
	 * @since 4.5.0
930
	 * @since 4.6.0 Added the `$blog_id` parameter.
931
	 *
932
	 * @param string $html    Custom logo HTML output.
933
	 * @param int    $blog_id ID of the blog to get the custom logo for.
934
	 */
935
	return apply_filters( 'get_custom_logo', $html, $blog_id );
936
}
937
938
/**
939
 * Displays a custom logo, linked to home.
940
 *
941
 * @since 4.5.0
942
 *
943
 * @param int $blog_id Optional. ID of the blog in question. Default is the ID of the current blog.
944
 */
945
function the_custom_logo( $blog_id = 0 ) {
946
	echo get_custom_logo( $blog_id );
947
}
948
949
/**
950
 * Returns document title for the current page.
951
 *
952
 * @since 4.4.0
953
 *
954
 * @global int $page  Page number of a single post.
955
 * @global int $paged Page number of a list of posts.
956
 *
957
 * @return string Tag with the document title.
958
 */
959
function wp_get_document_title() {
960
961
	/**
962
	 * Filters the document title before it is generated.
963
	 *
964
	 * Passing a non-empty value will short-circuit wp_get_document_title(),
965
	 * returning that value instead.
966
	 *
967
	 * @since 4.4.0
968
	 *
969
	 * @param string $title The document title. Default empty string.
970
	 */
971
	$title = apply_filters( 'pre_get_document_title', '' );
972
	if ( ! empty( $title ) ) {
973
		return $title;
974
	}
975
976
	global $page, $paged;
977
978
	$title = array(
979
		'title' => '',
980
	);
981
982
	// If it's a 404 page, use a "Page not found" title.
983
	if ( is_404() ) {
984
		$title['title'] = __( 'Page not found' );
985
986
	// If it's a search, use a dynamic search results title.
987
	} elseif ( is_search() ) {
988
		/* translators: %s: search phrase */
989
		$title['title'] = sprintf( __( 'Search Results for &#8220;%s&#8221;' ), get_search_query() );
990
991
	// If on the front page, use the site title.
992
	} elseif ( is_front_page() ) {
993
		$title['title'] = get_bloginfo( 'name', 'display' );
994
995
	// If on a post type archive, use the post type archive title.
996
	} elseif ( is_post_type_archive() ) {
997
		$title['title'] = post_type_archive_title( '', false );
998
999
	// If on a taxonomy archive, use the term title.
1000
	} elseif ( is_tax() ) {
1001
		$title['title'] = single_term_title( '', false );
1002
1003
	/*
1004
	 * If we're on the blog page that is not the homepage or
1005
	 * a single post of any post type, use the post title.
1006
	 */
1007
	} elseif ( is_home() || is_singular() ) {
1008
		$title['title'] = single_post_title( '', false );
1009
1010
	// If on a category or tag archive, use the term title.
1011
	} elseif ( is_category() || is_tag() ) {
1012
		$title['title'] = single_term_title( '', false );
1013
1014
	// If on an author archive, use the author's display name.
1015
	} elseif ( is_author() && $author = get_queried_object() ) {
1016
		$title['title'] = $author->display_name;
1017
1018
	// If it's a date archive, use the date as the title.
1019
	} elseif ( is_year() ) {
1020
		$title['title'] = get_the_date( _x( 'Y', 'yearly archives date format' ) );
1021
1022
	} elseif ( is_month() ) {
1023
		$title['title'] = get_the_date( _x( 'F Y', 'monthly archives date format' ) );
1024
1025
	} elseif ( is_day() ) {
1026
		$title['title'] = get_the_date();
1027
	}
1028
1029
	// Add a page number if necessary.
1030
	if ( ( $paged >= 2 || $page >= 2 ) && ! is_404() ) {
1031
		$title['page'] = sprintf( __( 'Page %s' ), max( $paged, $page ) );
1032
	}
1033
1034
	// Append the description or site title to give context.
1035
	if ( is_front_page() ) {
1036
		$title['tagline'] = get_bloginfo( 'description', 'display' );
1037
	} else {
1038
		$title['site'] = get_bloginfo( 'name', 'display' );
1039
	}
1040
1041
	/**
1042
	 * Filters the separator for the document title.
1043
	 *
1044
	 * @since 4.4.0
1045
	 *
1046
	 * @param string $sep Document title separator. Default '-'.
1047
	 */
1048
	$sep = apply_filters( 'document_title_separator', '-' );
1049
1050
	/**
1051
	 * Filters the parts of the document title.
1052
	 *
1053
	 * @since 4.4.0
1054
	 *
1055
	 * @param array $title {
1056
	 *     The document title parts.
1057
	 *
1058
	 *     @type string $title   Title of the viewed page.
1059
	 *     @type string $page    Optional. Page number if paginated.
1060
	 *     @type string $tagline Optional. Site description when on home page.
1061
	 *     @type string $site    Optional. Site title when not on home page.
1062
	 * }
1063
	 */
1064
	$title = apply_filters( 'document_title_parts', $title );
1065
1066
	$title = implode( " $sep ", array_filter( $title ) );
1067
	$title = wptexturize( $title );
1068
	$title = convert_chars( $title );
1069
	$title = esc_html( $title );
1070
	$title = capital_P_dangit( $title );
1071
1072
	return $title;
1073
}
1074
1075
/**
1076
 * Displays title tag with content.
1077
 *
1078
 * @ignore
1079
 * @since 4.1.0
1080
 * @since 4.4.0 Improved title output replaced `wp_title()`.
1081
 * @access private
1082
 */
1083
function _wp_render_title_tag() {
1084
	if ( ! current_theme_supports( 'title-tag' ) ) {
1085
		return;
1086
	}
1087
1088
	echo '<title>' . wp_get_document_title() . '</title>' . "\n";
1089
}
1090
1091
/**
1092
 * Display or retrieve page title for all areas of blog.
1093
 *
1094
 * By default, the page title will display the separator before the page title,
1095
 * so that the blog title will be before the page title. This is not good for
1096
 * title display, since the blog title shows up on most tabs and not what is
1097
 * important, which is the page that the user is looking at.
1098
 *
1099
 * There are also SEO benefits to having the blog title after or to the 'right'
1100
 * of the page title. However, it is mostly common sense to have the blog title
1101
 * to the right with most browsers supporting tabs. You can achieve this by
1102
 * using the seplocation parameter and setting the value to 'right'. This change
1103
 * was introduced around 2.5.0, in case backward compatibility of themes is
1104
 * important.
1105
 *
1106
 * @since 1.0.0
1107
 *
1108
 * @global WP_Locale $wp_locale
1109
 *
1110
 * @param string $sep         Optional, default is '&raquo;'. How to separate the various items
1111
 *                            within the page title.
1112
 * @param bool   $display     Optional, default is true. Whether to display or retrieve title.
1113
 * @param string $seplocation Optional. Direction to display title, 'right'.
1114
 * @return string|null String on retrieve, null when displaying.
1115
 */
1116
function wp_title( $sep = '&raquo;', $display = true, $seplocation = '' ) {
1117
	global $wp_locale;
1118
1119
	$m        = get_query_var( 'm' );
1120
	$year     = get_query_var( 'year' );
1121
	$monthnum = get_query_var( 'monthnum' );
1122
	$day      = get_query_var( 'day' );
1123
	$search   = get_query_var( 's' );
1124
	$title    = '';
1125
1126
	$t_sep = '%WP_TITLE_SEP%'; // Temporary separator, for accurate flipping, if necessary
1127
1128
	// If there is a post
1129
	if ( is_single() || ( is_home() && ! is_front_page() ) || ( is_page() && ! is_front_page() ) ) {
1130
		$title = single_post_title( '', false );
1131
	}
1132
1133
	// If there's a post type archive
1134
	if ( is_post_type_archive() ) {
1135
		$post_type = get_query_var( 'post_type' );
1136
		if ( is_array( $post_type ) ) {
1137
			$post_type = reset( $post_type );
1138
		}
1139
		$post_type_object = get_post_type_object( $post_type );
1140
		if ( ! $post_type_object->has_archive ) {
1141
			$title = post_type_archive_title( '', false );
1142
		}
1143
	}
1144
1145
	// If there's a category or tag
1146
	if ( is_category() || is_tag() ) {
1147
		$title = single_term_title( '', false );
1148
	}
1149
1150
	// If there's a taxonomy
1151
	if ( is_tax() ) {
1152
		$term = get_queried_object();
1153
		if ( $term ) {
1154
			$tax   = get_taxonomy( $term->taxonomy );
1155
			$title = single_term_title( $tax->labels->name . $t_sep, false );
1156
		}
1157
	}
1158
1159
	// If there's an author
1160
	if ( is_author() && ! is_post_type_archive() ) {
1161
		$author = get_queried_object();
1162
		if ( $author ) {
1163
			$title = $author->display_name;
1164
		}
1165
	}
1166
1167
	// Post type archives with has_archive should override terms.
1168
	if ( is_post_type_archive() && $post_type_object->has_archive ) {
0 ignored issues
show
The variable $post_type_object does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
1169
		$title = post_type_archive_title( '', false );
1170
	}
1171
1172
	// If there's a month
1173
	if ( is_archive() && ! empty( $m ) ) {
1174
		$my_year  = substr( $m, 0, 4 );
1175
		$my_month = $wp_locale->get_month( substr( $m, 4, 2 ) );
1176
		$my_day   = intval( substr( $m, 6, 2 ) );
1177
		$title    = $my_year . ( $my_month ? $t_sep . $my_month : '' ) . ( $my_day ? $t_sep . $my_day : '' );
1178
	}
1179
1180
	// If there's a year
1181
	if ( is_archive() && ! empty( $year ) ) {
1182
		$title = $year;
1183
		if ( ! empty( $monthnum ) ) {
1184
			$title .= $t_sep . $wp_locale->get_month( $monthnum );
1185
		}
1186
		if ( ! empty( $day ) ) {
1187
			$title .= $t_sep . zeroise( $day, 2 );
1188
		}
1189
	}
1190
1191
	// If it's a search
1192
	if ( is_search() ) {
1193
		/* translators: 1: separator, 2: search phrase */
1194
		$title = sprintf( __( 'Search Results %1$s %2$s' ), $t_sep, strip_tags( $search ) );
1195
	}
1196
1197
	// If it's a 404 page
1198
	if ( is_404() ) {
1199
		$title = __( 'Page not found' );
1200
	}
1201
1202
	$prefix = '';
1203
	if ( ! empty( $title ) ) {
1204
		$prefix = " $sep ";
1205
	}
1206
1207
	/**
1208
	 * Filters the parts of the page title.
1209
	 *
1210
	 * @since 4.0.0
1211
	 *
1212
	 * @param array $title_array Parts of the page title.
1213
	 */
1214
	$title_array = apply_filters( 'wp_title_parts', explode( $t_sep, $title ) );
1215
1216
	// Determines position of the separator and direction of the breadcrumb
1217
	if ( 'right' == $seplocation ) { // sep on right, so reverse the order
1218
		$title_array = array_reverse( $title_array );
1219
		$title       = implode( " $sep ", $title_array ) . $prefix;
1220
	} else {
1221
		$title = $prefix . implode( " $sep ", $title_array );
1222
	}
1223
1224
	/**
1225
	 * Filters the text of the page title.
1226
	 *
1227
	 * @since 2.0.0
1228
	 *
1229
	 * @param string $title Page title.
1230
	 * @param string $sep Title separator.
1231
	 * @param string $seplocation Location of the separator (left or right).
1232
	 */
1233
	$title = apply_filters( 'wp_title', $title, $sep, $seplocation );
1234
1235
	// Send it out
1236
	if ( $display ) {
1237
		echo $title;
1238
	} else {
1239
		return $title;
1240
	}
1241
}
1242
1243
/**
1244
 * Display or retrieve page title for post.
1245
 *
1246
 * This is optimized for single.php template file for displaying the post title.
1247
 *
1248
 * It does not support placing the separator after the title, but by leaving the
1249
 * prefix parameter empty, you can set the title separator manually. The prefix
1250
 * does not automatically place a space between the prefix, so if there should
1251
 * be a space, the parameter value will need to have it at the end.
1252
 *
1253
 * @since 0.71
1254
 *
1255
 * @param string $prefix  Optional. What to display before the title.
1256
 * @param bool   $display Optional, default is true. Whether to display or retrieve title.
1257
 * @return string|void Title when retrieving.
1258
 */
1259
function single_post_title( $prefix = '', $display = true ) {
1260
	$_post = get_queried_object();
1261
1262
	if ( !isset($_post->post_title) )
1263
		return;
1264
1265
	/**
1266
	 * Filters the page title for a single post.
1267
	 *
1268
	 * @since 0.71
1269
	 *
1270
	 * @param string $_post_title The single post page title.
1271
	 * @param object $_post       The current queried object as returned by get_queried_object().
1272
	 */
1273
	$title = apply_filters( 'single_post_title', $_post->post_title, $_post );
1274
	if ( $display )
1275
		echo $prefix . $title;
1276
	else
1277
		return $prefix . $title;
1278
}
1279
1280
/**
1281
 * Display or retrieve title for a post type archive.
1282
 *
1283
 * This is optimized for archive.php and archive-{$post_type}.php template files
1284
 * for displaying the title of the post type.
1285
 *
1286
 * @since 3.1.0
1287
 *
1288
 * @param string $prefix  Optional. What to display before the title.
1289
 * @param bool   $display Optional, default is true. Whether to display or retrieve title.
1290
 * @return string|void Title when retrieving, null when displaying or failure.
1291
 */
1292
function post_type_archive_title( $prefix = '', $display = true ) {
1293
	if ( ! is_post_type_archive() )
1294
		return;
1295
1296
	$post_type = get_query_var( 'post_type' );
1297
	if ( is_array( $post_type ) )
1298
		$post_type = reset( $post_type );
1299
1300
	$post_type_obj = get_post_type_object( $post_type );
1301
1302
	/**
1303
	 * Filters the post type archive title.
1304
	 *
1305
	 * @since 3.1.0
1306
	 *
1307
	 * @param string $post_type_name Post type 'name' label.
1308
	 * @param string $post_type      Post type.
1309
	 */
1310
	$title = apply_filters( 'post_type_archive_title', $post_type_obj->labels->name, $post_type );
1311
1312
	if ( $display )
1313
		echo $prefix . $title;
1314
	else
1315
		return $prefix . $title;
1316
}
1317
1318
/**
1319
 * Display or retrieve page title for category archive.
1320
 *
1321
 * Useful for category template files for displaying the category page title.
1322
 * The prefix does not automatically place a space between the prefix, so if
1323
 * there should be a space, the parameter value will need to have it at the end.
1324
 *
1325
 * @since 0.71
1326
 *
1327
 * @param string $prefix  Optional. What to display before the title.
1328
 * @param bool   $display Optional, default is true. Whether to display or retrieve title.
1329
 * @return string|void Title when retrieving.
1330
 */
1331
function single_cat_title( $prefix = '', $display = true ) {
1332
	return single_term_title( $prefix, $display );
1333
}
1334
1335
/**
1336
 * Display or retrieve page title for tag post archive.
1337
 *
1338
 * Useful for tag template files for displaying the tag page title. The prefix
1339
 * does not automatically place a space between the prefix, so if there should
1340
 * be a space, the parameter value will need to have it at the end.
1341
 *
1342
 * @since 2.3.0
1343
 *
1344
 * @param string $prefix  Optional. What to display before the title.
1345
 * @param bool   $display Optional, default is true. Whether to display or retrieve title.
1346
 * @return string|void Title when retrieving.
1347
 */
1348
function single_tag_title( $prefix = '', $display = true ) {
1349
	return single_term_title( $prefix, $display );
1350
}
1351
1352
/**
1353
 * Display or retrieve page title for taxonomy term archive.
1354
 *
1355
 * Useful for taxonomy term template files for displaying the taxonomy term page title.
1356
 * The prefix does not automatically place a space between the prefix, so if there should
1357
 * be a space, the parameter value will need to have it at the end.
1358
 *
1359
 * @since 3.1.0
1360
 *
1361
 * @param string $prefix  Optional. What to display before the title.
1362
 * @param bool   $display Optional, default is true. Whether to display or retrieve title.
1363
 * @return string|void Title when retrieving.
1364
 */
1365
function single_term_title( $prefix = '', $display = true ) {
1366
	$term = get_queried_object();
1367
1368
	if ( !$term )
1369
		return;
1370
1371
	if ( is_category() ) {
1372
		/**
1373
		 * Filters the category archive page title.
1374
		 *
1375
		 * @since 2.0.10
1376
		 *
1377
		 * @param string $term_name Category name for archive being displayed.
1378
		 */
1379
		$term_name = apply_filters( 'single_cat_title', $term->name );
1380
	} elseif ( is_tag() ) {
1381
		/**
1382
		 * Filters the tag archive page title.
1383
		 *
1384
		 * @since 2.3.0
1385
		 *
1386
		 * @param string $term_name Tag name for archive being displayed.
1387
		 */
1388
		$term_name = apply_filters( 'single_tag_title', $term->name );
1389
	} elseif ( is_tax() ) {
1390
		/**
1391
		 * Filters the custom taxonomy archive page title.
1392
		 *
1393
		 * @since 3.1.0
1394
		 *
1395
		 * @param string $term_name Term name for archive being displayed.
1396
		 */
1397
		$term_name = apply_filters( 'single_term_title', $term->name );
1398
	} else {
1399
		return;
1400
	}
1401
1402
	if ( empty( $term_name ) )
1403
		return;
1404
1405
	if ( $display )
1406
		echo $prefix . $term_name;
1407
	else
1408
		return $prefix . $term_name;
1409
}
1410
1411
/**
1412
 * Display or retrieve page title for post archive based on date.
1413
 *
1414
 * Useful for when the template only needs to display the month and year,
1415
 * if either are available. The prefix does not automatically place a space
1416
 * between the prefix, so if there should be a space, the parameter value
1417
 * will need to have it at the end.
1418
 *
1419
 * @since 0.71
1420
 *
1421
 * @global WP_Locale $wp_locale
1422
 *
1423
 * @param string $prefix  Optional. What to display before the title.
1424
 * @param bool   $display Optional, default is true. Whether to display or retrieve title.
1425
 * @return string|void Title when retrieving.
0 ignored issues
show
Should the return type not be false|string|null?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
1426
 */
1427
function single_month_title($prefix = '', $display = true ) {
1428
	global $wp_locale;
1429
1430
	$m = get_query_var('m');
1431
	$year = get_query_var('year');
1432
	$monthnum = get_query_var('monthnum');
1433
1434
	if ( !empty($monthnum) && !empty($year) ) {
1435
		$my_year = $year;
1436
		$my_month = $wp_locale->get_month($monthnum);
1437
	} elseif ( !empty($m) ) {
1438
		$my_year = substr($m, 0, 4);
1439
		$my_month = $wp_locale->get_month(substr($m, 4, 2));
1440
	}
1441
1442
	if ( empty($my_month) )
1443
		return false;
1444
1445
	$result = $prefix . $my_month . $prefix . $my_year;
0 ignored issues
show
The variable $my_year does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
1446
1447
	if ( !$display )
1448
		return $result;
1449
	echo $result;
1450
}
1451
1452
/**
1453
 * Display the archive title based on the queried object.
1454
 *
1455
 * @since 4.1.0
1456
 *
1457
 * @see get_the_archive_title()
1458
 *
1459
 * @param string $before Optional. Content to prepend to the title. Default empty.
1460
 * @param string $after  Optional. Content to append to the title. Default empty.
1461
 */
1462
function the_archive_title( $before = '', $after = '' ) {
1463
	$title = get_the_archive_title();
1464
1465
	if ( ! empty( $title ) ) {
1466
		echo $before . $title . $after;
1467
	}
1468
}
1469
1470
/**
1471
 * Retrieve the archive title based on the queried object.
1472
 *
1473
 * @since 4.1.0
1474
 *
1475
 * @return string Archive title.
1476
 */
1477
function get_the_archive_title() {
1478
	if ( is_category() ) {
1479
		/* translators: Category archive title. 1: Category name */
1480
		$title = sprintf( __( 'Category: %s' ), single_cat_title( '', false ) );
1481
	} elseif ( is_tag() ) {
1482
		/* translators: Tag archive title. 1: Tag name */
1483
		$title = sprintf( __( 'Tag: %s' ), single_tag_title( '', false ) );
1484
	} elseif ( is_author() ) {
1485
		/* translators: Author archive title. 1: Author name */
1486
		$title = sprintf( __( 'Author: %s' ), '<span class="vcard">' . get_the_author() . '</span>' );
1487
	} elseif ( is_year() ) {
1488
		/* translators: Yearly archive title. 1: Year */
1489
		$title = sprintf( __( 'Year: %s' ), get_the_date( _x( 'Y', 'yearly archives date format' ) ) );
1490
	} elseif ( is_month() ) {
1491
		/* translators: Monthly archive title. 1: Month name and year */
1492
		$title = sprintf( __( 'Month: %s' ), get_the_date( _x( 'F Y', 'monthly archives date format' ) ) );
1493
	} elseif ( is_day() ) {
1494
		/* translators: Daily archive title. 1: Date */
1495
		$title = sprintf( __( 'Day: %s' ), get_the_date( _x( 'F j, Y', 'daily archives date format' ) ) );
1496
	} elseif ( is_tax( 'post_format' ) ) {
1497
		if ( is_tax( 'post_format', 'post-format-aside' ) ) {
1498
			$title = _x( 'Asides', 'post format archive title' );
1499
		} elseif ( is_tax( 'post_format', 'post-format-gallery' ) ) {
1500
			$title = _x( 'Galleries', 'post format archive title' );
1501
		} elseif ( is_tax( 'post_format', 'post-format-image' ) ) {
1502
			$title = _x( 'Images', 'post format archive title' );
1503
		} elseif ( is_tax( 'post_format', 'post-format-video' ) ) {
1504
			$title = _x( 'Videos', 'post format archive title' );
1505
		} elseif ( is_tax( 'post_format', 'post-format-quote' ) ) {
1506
			$title = _x( 'Quotes', 'post format archive title' );
1507
		} elseif ( is_tax( 'post_format', 'post-format-link' ) ) {
1508
			$title = _x( 'Links', 'post format archive title' );
1509
		} elseif ( is_tax( 'post_format', 'post-format-status' ) ) {
1510
			$title = _x( 'Statuses', 'post format archive title' );
1511
		} elseif ( is_tax( 'post_format', 'post-format-audio' ) ) {
1512
			$title = _x( 'Audio', 'post format archive title' );
1513
		} elseif ( is_tax( 'post_format', 'post-format-chat' ) ) {
1514
			$title = _x( 'Chats', 'post format archive title' );
1515
		}
1516
	} elseif ( is_post_type_archive() ) {
1517
		/* translators: Post type archive title. 1: Post type name */
1518
		$title = sprintf( __( 'Archives: %s' ), post_type_archive_title( '', false ) );
1519
	} elseif ( is_tax() ) {
1520
		$tax = get_taxonomy( get_queried_object()->taxonomy );
1521
		/* translators: Taxonomy term archive title. 1: Taxonomy singular name, 2: Current taxonomy term */
1522
		$title = sprintf( __( '%1$s: %2$s' ), $tax->labels->singular_name, single_term_title( '', false ) );
1523
	} else {
1524
		$title = __( 'Archives' );
1525
	}
1526
1527
	/**
1528
	 * Filters the archive title.
1529
	 *
1530
	 * @since 4.1.0
1531
	 *
1532
	 * @param string $title Archive title to be displayed.
1533
	 */
1534
	return apply_filters( 'get_the_archive_title', $title );
0 ignored issues
show
The variable $title does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
1535
}
1536
1537
/**
1538
 * Display category, tag, term, or author description.
1539
 *
1540
 * @since 4.1.0
1541
 *
1542
 * @see get_the_archive_description()
1543
 *
1544
 * @param string $before Optional. Content to prepend to the description. Default empty.
1545
 * @param string $after  Optional. Content to append to the description. Default empty.
1546
 */
1547
function the_archive_description( $before = '', $after = '' ) {
1548
	$description = get_the_archive_description();
1549
	if ( $description ) {
1550
		echo $before . $description . $after;
1551
	}
1552
}
1553
1554
/**
1555
 * Retrieve category, tag, term, or author description.
1556
 *
1557
 * @since 4.1.0
1558
 * @since 4.7.0 Added support for author archives.
1559
 *
1560
 * @see term_description()
1561
 *
1562
 * @return string Archive description.
1563
 */
1564
function get_the_archive_description() {
1565
	if ( is_author() ) {
1566
		$description = get_the_author_meta( 'description' );
1567
	} else {
1568
		$description = term_description();
1569
	}
1570
1571
	/**
1572
	 * Filters the archive description.
1573
	 *
1574
	 * @since 4.1.0
1575
	 *
1576
	 * @param string $description Archive description to be displayed.
1577
	 */
1578
	return apply_filters( 'get_the_archive_description', $description );
1579
}
1580
1581
/**
1582
 * Retrieve archive link content based on predefined or custom code.
1583
 *
1584
 * The format can be one of four styles. The 'link' for head element, 'option'
1585
 * for use in the select element, 'html' for use in list (either ol or ul HTML
1586
 * elements). Custom content is also supported using the before and after
1587
 * parameters.
1588
 *
1589
 * The 'link' format uses the `<link>` HTML element with the **archives**
1590
 * relationship. The before and after parameters are not used. The text
1591
 * parameter is used to describe the link.
1592
 *
1593
 * The 'option' format uses the option HTML element for use in select element.
1594
 * The value is the url parameter and the before and after parameters are used
1595
 * between the text description.
1596
 *
1597
 * The 'html' format, which is the default, uses the li HTML element for use in
1598
 * the list HTML elements. The before parameter is before the link and the after
1599
 * parameter is after the closing link.
1600
 *
1601
 * The custom format uses the before parameter before the link ('a' HTML
1602
 * element) and the after parameter after the closing link tag. If the above
1603
 * three values for the format are not used, then custom format is assumed.
1604
 *
1605
 * @since 1.0.0
1606
 *
1607
 * @param string $url    URL to archive.
1608
 * @param string $text   Archive text description.
1609
 * @param string $format Optional, default is 'html'. Can be 'link', 'option', 'html', or custom.
1610
 * @param string $before Optional. Content to prepend to the description. Default empty.
1611
 * @param string $after  Optional. Content to append to the description. Default empty.
1612
 * @return string HTML link content for archive.
1613
 */
1614
function get_archives_link($url, $text, $format = 'html', $before = '', $after = '') {
1615
	$text = wptexturize($text);
1616
	$url = esc_url($url);
1617
1618
	if ('link' == $format)
1619
		$link_html = "\t<link rel='archives' title='" . esc_attr( $text ) . "' href='$url' />\n";
1620
	elseif ('option' == $format)
1621
		$link_html = "\t<option value='$url'>$before $text $after</option>\n";
1622
	elseif ('html' == $format)
1623
		$link_html = "\t<li>$before<a href='$url'>$text</a>$after</li>\n";
1624
	else // custom
1625
		$link_html = "\t$before<a href='$url'>$text</a>$after\n";
1626
1627
	/**
1628
	 * Filters the archive link content.
1629
	 *
1630
	 * @since 2.6.0
1631
	 * @since 4.5.0 Added the `$url`, `$text`, `$format`, `$before`, and `$after` parameters.
1632
	 *
1633
	 * @param string $link_html The archive HTML link content.
1634
	 * @param string $url       URL to archive.
1635
	 * @param string $text      Archive text description.
1636
	 * @param string $format    Link format. Can be 'link', 'option', 'html', or custom.
1637
	 * @param string $before    Content to prepend to the description.
1638
	 * @param string $after     Content to append to the description.
1639
	 */
1640
	return apply_filters( 'get_archives_link', $link_html, $url, $text, $format, $before, $after );
1641
}
1642
1643
/**
1644
 * Display archive links based on type and format.
1645
 *
1646
 * @since 1.2.0
1647
 * @since 4.4.0 $post_type arg was added.
1648
 *
1649
 * @see get_archives_link()
1650
 *
1651
 * @global wpdb      $wpdb
1652
 * @global WP_Locale $wp_locale
1653
 *
1654
 * @param string|array $args {
1655
 *     Default archive links arguments. Optional.
1656
 *
1657
 *     @type string     $type            Type of archive to retrieve. Accepts 'daily', 'weekly', 'monthly',
1658
 *                                       'yearly', 'postbypost', or 'alpha'. Both 'postbypost' and 'alpha'
1659
 *                                       display the same archive link list as well as post titles instead
1660
 *                                       of displaying dates. The difference between the two is that 'alpha'
1661
 *                                       will order by post title and 'postbypost' will order by post date.
1662
 *                                       Default 'monthly'.
1663
 *     @type string|int $limit           Number of links to limit the query to. Default empty (no limit).
1664
 *     @type string     $format          Format each link should take using the $before and $after args.
1665
 *                                       Accepts 'link' (`<link>` tag), 'option' (`<option>` tag), 'html'
1666
 *                                       (`<li>` tag), or a custom format, which generates a link anchor
1667
 *                                       with $before preceding and $after succeeding. Default 'html'.
1668
 *     @type string     $before          Markup to prepend to the beginning of each link. Default empty.
1669
 *     @type string     $after           Markup to append to the end of each link. Default empty.
1670
 *     @type bool       $show_post_count Whether to display the post count alongside the link. Default false.
1671
 *     @type bool|int   $echo            Whether to echo or return the links list. Default 1|true to echo.
1672
 *     @type string     $order           Whether to use ascending or descending order. Accepts 'ASC', or 'DESC'.
1673
 *                                       Default 'DESC'.
1674
 *     @type string     $post_type       Post type. Default 'post'.
1675
 * }
1676
 * @return string|void String when retrieving.
1677
 */
1678
function wp_get_archives( $args = '' ) {
1679
	global $wpdb, $wp_locale;
1680
1681
	$defaults = array(
1682
		'type' => 'monthly', 'limit' => '',
1683
		'format' => 'html', 'before' => '',
1684
		'after' => '', 'show_post_count' => false,
1685
		'echo' => 1, 'order' => 'DESC',
1686
		'post_type' => 'post'
1687
	);
1688
1689
	$r = wp_parse_args( $args, $defaults );
1690
1691
	$post_type_object = get_post_type_object( $r['post_type'] );
1692
	if ( ! is_post_type_viewable( $post_type_object ) ) {
0 ignored issues
show
It seems like $post_type_object defined by get_post_type_object($r['post_type']) on line 1691 can be null; however, is_post_type_viewable() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
1693
		return;
1694
	}
1695
	$r['post_type'] = $post_type_object->name;
1696
1697
	if ( '' == $r['type'] ) {
1698
		$r['type'] = 'monthly';
1699
	}
1700
1701
	if ( ! empty( $r['limit'] ) ) {
1702
		$r['limit'] = absint( $r['limit'] );
1703
		$r['limit'] = ' LIMIT ' . $r['limit'];
1704
	}
1705
1706
	$order = strtoupper( $r['order'] );
1707
	if ( $order !== 'ASC' ) {
1708
		$order = 'DESC';
1709
	}
1710
1711
	// this is what will separate dates on weekly archive links
1712
	$archive_week_separator = '&#8211;';
1713
1714
	$sql_where = $wpdb->prepare( "WHERE post_type = %s AND post_status = 'publish'", $r['post_type'] );
1715
1716
	/**
1717
	 * Filters the SQL WHERE clause for retrieving archives.
1718
	 *
1719
	 * @since 2.2.0
1720
	 *
1721
	 * @param string $sql_where Portion of SQL query containing the WHERE clause.
1722
	 * @param array  $r         An array of default arguments.
1723
	 */
1724
	$where = apply_filters( 'getarchives_where', $sql_where, $r );
1725
1726
	/**
1727
	 * Filters the SQL JOIN clause for retrieving archives.
1728
	 *
1729
	 * @since 2.2.0
1730
	 *
1731
	 * @param string $sql_join Portion of SQL query containing JOIN clause.
1732
	 * @param array  $r        An array of default arguments.
1733
	 */
1734
	$join = apply_filters( 'getarchives_join', '', $r );
1735
1736
	$output = '';
1737
1738
	$last_changed = wp_cache_get_last_changed( 'posts' );
1739
1740
	$limit = $r['limit'];
1741
1742
	if ( 'monthly' == $r['type'] ) {
1743
		$query = "SELECT YEAR(post_date) AS `year`, MONTH(post_date) AS `month`, count(ID) as posts FROM $wpdb->posts $join $where GROUP BY YEAR(post_date), MONTH(post_date) ORDER BY post_date $order $limit";
1744
		$key = md5( $query );
1745
		$key = "wp_get_archives:$key:$last_changed";
1746 View Code Duplication
		if ( ! $results = wp_cache_get( $key, 'posts' ) ) {
1747
			$results = $wpdb->get_results( $query );
1748
			wp_cache_set( $key, $results, 'posts' );
1749
		}
1750
		if ( $results ) {
1751
			$after = $r['after'];
1752
			foreach ( (array) $results as $result ) {
1753
				$url = get_month_link( $result->year, $result->month );
1754
				if ( 'post' !== $r['post_type'] ) {
1755
					$url = add_query_arg( 'post_type', $r['post_type'], $url );
1756
				}
1757
				/* translators: 1: month name, 2: 4-digit year */
1758
				$text = sprintf( __( '%1$s %2$d' ), $wp_locale->get_month( $result->month ), $result->year );
1759 View Code Duplication
				if ( $r['show_post_count'] ) {
1760
					$r['after'] = '&nbsp;(' . $result->posts . ')' . $after;
1761
				}
1762
				$output .= get_archives_link( $url, $text, $r['format'], $r['before'], $r['after'] );
1763
			}
1764
		}
1765
	} elseif ( 'yearly' == $r['type'] ) {
1766
		$query = "SELECT YEAR(post_date) AS `year`, count(ID) as posts FROM $wpdb->posts $join $where GROUP BY YEAR(post_date) ORDER BY post_date $order $limit";
1767
		$key = md5( $query );
1768
		$key = "wp_get_archives:$key:$last_changed";
1769 View Code Duplication
		if ( ! $results = wp_cache_get( $key, 'posts' ) ) {
1770
			$results = $wpdb->get_results( $query );
1771
			wp_cache_set( $key, $results, 'posts' );
1772
		}
1773
		if ( $results ) {
1774
			$after = $r['after'];
1775
			foreach ( (array) $results as $result) {
1776
				$url = get_year_link( $result->year );
1777
				if ( 'post' !== $r['post_type'] ) {
1778
					$url = add_query_arg( 'post_type', $r['post_type'], $url );
1779
				}
1780
				$text = sprintf( '%d', $result->year );
1781 View Code Duplication
				if ( $r['show_post_count'] ) {
1782
					$r['after'] = '&nbsp;(' . $result->posts . ')' . $after;
1783
				}
1784
				$output .= get_archives_link( $url, $text, $r['format'], $r['before'], $r['after'] );
1785
			}
1786
		}
1787
	} elseif ( 'daily' == $r['type'] ) {
1788
		$query = "SELECT YEAR(post_date) AS `year`, MONTH(post_date) AS `month`, DAYOFMONTH(post_date) AS `dayofmonth`, count(ID) as posts FROM $wpdb->posts $join $where GROUP BY YEAR(post_date), MONTH(post_date), DAYOFMONTH(post_date) ORDER BY post_date $order $limit";
1789
		$key = md5( $query );
1790
		$key = "wp_get_archives:$key:$last_changed";
1791 View Code Duplication
		if ( ! $results = wp_cache_get( $key, 'posts' ) ) {
1792
			$results = $wpdb->get_results( $query );
1793
			wp_cache_set( $key, $results, 'posts' );
1794
		}
1795
		if ( $results ) {
1796
			$after = $r['after'];
1797
			foreach ( (array) $results as $result ) {
1798
				$url  = get_day_link( $result->year, $result->month, $result->dayofmonth );
1799
				if ( 'post' !== $r['post_type'] ) {
1800
					$url = add_query_arg( 'post_type', $r['post_type'], $url );
1801
				}
1802
				$date = sprintf( '%1$d-%2$02d-%3$02d 00:00:00', $result->year, $result->month, $result->dayofmonth );
1803
				$text = mysql2date( get_option( 'date_format' ), $date );
1804 View Code Duplication
				if ( $r['show_post_count'] ) {
1805
					$r['after'] = '&nbsp;(' . $result->posts . ')' . $after;
1806
				}
1807
				$output .= get_archives_link( $url, $text, $r['format'], $r['before'], $r['after'] );
1808
			}
1809
		}
1810
	} elseif ( 'weekly' == $r['type'] ) {
1811
		$week = _wp_mysql_week( '`post_date`' );
1812
		$query = "SELECT DISTINCT $week AS `week`, YEAR( `post_date` ) AS `yr`, DATE_FORMAT( `post_date`, '%Y-%m-%d' ) AS `yyyymmdd`, count( `ID` ) AS `posts` FROM `$wpdb->posts` $join $where GROUP BY $week, YEAR( `post_date` ) ORDER BY `post_date` $order $limit";
1813
		$key = md5( $query );
1814
		$key = "wp_get_archives:$key:$last_changed";
1815 View Code Duplication
		if ( ! $results = wp_cache_get( $key, 'posts' ) ) {
1816
			$results = $wpdb->get_results( $query );
1817
			wp_cache_set( $key, $results, 'posts' );
1818
		}
1819
		$arc_w_last = '';
1820
		if ( $results ) {
1821
			$after = $r['after'];
1822
			foreach ( (array) $results as $result ) {
1823
				if ( $result->week != $arc_w_last ) {
1824
					$arc_year       = $result->yr;
1825
					$arc_w_last     = $result->week;
1826
					$arc_week       = get_weekstartend( $result->yyyymmdd, get_option( 'start_of_week' ) );
1827
					$arc_week_start = date_i18n( get_option( 'date_format' ), $arc_week['start'] );
1828
					$arc_week_end   = date_i18n( get_option( 'date_format' ), $arc_week['end'] );
1829
					$url            = add_query_arg( array( 'm' => $arc_year, 'w' => $result->week, ), home_url( '/' ) );
1830
					if ( 'post' !== $r['post_type'] ) {
1831
						$url = add_query_arg( 'post_type', $r['post_type'], $url );
1832
					}
1833
					$text           = $arc_week_start . $archive_week_separator . $arc_week_end;
1834 View Code Duplication
					if ( $r['show_post_count'] ) {
1835
						$r['after'] = '&nbsp;(' . $result->posts . ')' . $after;
1836
					}
1837
					$output .= get_archives_link( $url, $text, $r['format'], $r['before'], $r['after'] );
1838
				}
1839
			}
1840
		}
1841
	} elseif ( ( 'postbypost' == $r['type'] ) || ('alpha' == $r['type'] ) ) {
1842
		$orderby = ( 'alpha' == $r['type'] ) ? 'post_title ASC ' : 'post_date DESC, ID DESC ';
1843
		$query = "SELECT * FROM $wpdb->posts $join $where ORDER BY $orderby $limit";
1844
		$key = md5( $query );
1845
		$key = "wp_get_archives:$key:$last_changed";
1846 View Code Duplication
		if ( ! $results = wp_cache_get( $key, 'posts' ) ) {
1847
			$results = $wpdb->get_results( $query );
1848
			wp_cache_set( $key, $results, 'posts' );
1849
		}
1850
		if ( $results ) {
1851
			foreach ( (array) $results as $result ) {
1852
				if ( $result->post_date != '0000-00-00 00:00:00' ) {
1853
					$url = get_permalink( $result );
1854
					if ( $result->post_title ) {
1855
						/** This filter is documented in wp-includes/post-template.php */
1856
						$text = strip_tags( apply_filters( 'the_title', $result->post_title, $result->ID ) );
1857
					} else {
1858
						$text = $result->ID;
1859
					}
1860
					$output .= get_archives_link( $url, $text, $r['format'], $r['before'], $r['after'] );
0 ignored issues
show
It seems like $url defined by get_permalink($result) on line 1853 can also be of type false; however, get_archives_link() does only seem to accept string, did you maybe forget to handle an error condition?

This check looks for type mismatches where the missing type is false. This is usually indicative of an error condtion.

Consider the follow example

<?php

function getDate($date)
{
    if ($date !== null) {
        return new DateTime($date);
    }

    return false;
}

This function either returns a new DateTime object or false, if there was an error. This is a typical pattern in PHP programming to show that an error has occurred without raising an exception. The calling code should check for this returned false before passing on the value to another function or method that may not be able to handle a false.

Loading history...
1861
				}
1862
			}
1863
		}
1864
	}
1865
	if ( $r['echo'] ) {
1866
		echo $output;
1867
	} else {
1868
		return $output;
1869
	}
1870
}
1871
1872
/**
1873
 * Get number of days since the start of the week.
1874
 *
1875
 * @since 1.5.0
1876
 *
1877
 * @param int $num Number of day.
1878
 * @return float Days since the start of the week.
1879
 */
1880
function calendar_week_mod($num) {
1881
	$base = 7;
1882
	return ($num - $base*floor($num/$base));
1883
}
1884
1885
/**
1886
 * Display calendar with days that have posts as links.
1887
 *
1888
 * The calendar is cached, which will be retrieved, if it exists. If there are
1889
 * no posts for the month, then it will not be displayed.
1890
 *
1891
 * @since 1.0.0
1892
 *
1893
 * @global wpdb      $wpdb
1894
 * @global int       $m
1895
 * @global int       $monthnum
1896
 * @global int       $year
1897
 * @global WP_Locale $wp_locale
1898
 * @global array     $posts
1899
 *
1900
 * @param bool $initial Optional, default is true. Use initial calendar names.
1901
 * @param bool $echo    Optional, default is true. Set to false for return.
1902
 * @return string|void String when retrieving.
1903
 */
1904
function get_calendar( $initial = true, $echo = true ) {
1905
	global $wpdb, $m, $monthnum, $year, $wp_locale, $posts;
1906
1907
	$key = md5( $m . $monthnum . $year );
1908
	$cache = wp_cache_get( 'get_calendar', 'calendar' );
1909
1910
	if ( $cache && is_array( $cache ) && isset( $cache[ $key ] ) ) {
1911
		/** This filter is documented in wp-includes/general-template.php */
1912
		$output = apply_filters( 'get_calendar', $cache[ $key ] );
1913
1914
		if ( $echo ) {
1915
			echo $output;
1916
			return;
1917
		}
1918
1919
		return $output;
1920
	}
1921
1922
	if ( ! is_array( $cache ) ) {
1923
		$cache = array();
1924
	}
1925
1926
	// Quick check. If we have no posts at all, abort!
1927
	if ( ! $posts ) {
1928
		$gotsome = $wpdb->get_var("SELECT 1 as test FROM $wpdb->posts WHERE post_type = 'post' AND post_status = 'publish' LIMIT 1");
1929
		if ( ! $gotsome ) {
1930
			$cache[ $key ] = '';
1931
			wp_cache_set( 'get_calendar', $cache, 'calendar' );
1932
			return;
1933
		}
1934
	}
1935
1936
	if ( isset( $_GET['w'] ) ) {
1937
		$w = (int) $_GET['w'];
1938
	}
1939
	// week_begins = 0 stands for Sunday
1940
	$week_begins = (int) get_option( 'start_of_week' );
1941
	$ts = current_time( 'timestamp' );
1942
1943
	// Let's figure out when we are
1944
	if ( ! empty( $monthnum ) && ! empty( $year ) ) {
1945
		$thismonth = zeroise( intval( $monthnum ), 2 );
1946
		$thisyear = (int) $year;
1947
	} elseif ( ! empty( $w ) ) {
1948
		// We need to get the month from MySQL
1949
		$thisyear = (int) substr( $m, 0, 4 );
1950
		//it seems MySQL's weeks disagree with PHP's
1951
		$d = ( ( $w - 1 ) * 7 ) + 6;
1952
		$thismonth = $wpdb->get_var("SELECT DATE_FORMAT((DATE_ADD('{$thisyear}0101', INTERVAL $d DAY) ), '%m')");
1953
	} elseif ( ! empty( $m ) ) {
1954
		$thisyear = (int) substr( $m, 0, 4 );
1955
		if ( strlen( $m ) < 6 ) {
1956
			$thismonth = '01';
1957
		} else {
1958
			$thismonth = zeroise( (int) substr( $m, 4, 2 ), 2 );
1959
		}
1960
	} else {
1961
		$thisyear = gmdate( 'Y', $ts );
1962
		$thismonth = gmdate( 'm', $ts );
1963
	}
1964
1965
	$unixmonth = mktime( 0, 0 , 0, $thismonth, 1, $thisyear );
1966
	$last_day = date( 't', $unixmonth );
1967
1968
	// Get the next and previous month and year with at least one post
1969
	$previous = $wpdb->get_row("SELECT MONTH(post_date) AS month, YEAR(post_date) AS year
1970
		FROM $wpdb->posts
1971
		WHERE post_date < '$thisyear-$thismonth-01'
1972
		AND post_type = 'post' AND post_status = 'publish'
1973
			ORDER BY post_date DESC
1974
			LIMIT 1");
1975
	$next = $wpdb->get_row("SELECT MONTH(post_date) AS month, YEAR(post_date) AS year
1976
		FROM $wpdb->posts
1977
		WHERE post_date > '$thisyear-$thismonth-{$last_day} 23:59:59'
1978
		AND post_type = 'post' AND post_status = 'publish'
1979
			ORDER BY post_date ASC
1980
			LIMIT 1");
1981
1982
	/* translators: Calendar caption: 1: month name, 2: 4-digit year */
1983
	$calendar_caption = _x('%1$s %2$s', 'calendar caption');
1984
	$calendar_output = '<table id="wp-calendar">
1985
	<caption>' . sprintf(
1986
		$calendar_caption,
1987
		$wp_locale->get_month( $thismonth ),
1988
		date( 'Y', $unixmonth )
1989
	) . '</caption>
1990
	<thead>
1991
	<tr>';
1992
1993
	$myweek = array();
1994
1995
	for ( $wdcount = 0; $wdcount <= 6; $wdcount++ ) {
1996
		$myweek[] = $wp_locale->get_weekday( ( $wdcount + $week_begins ) % 7 );
1997
	}
1998
1999
	foreach ( $myweek as $wd ) {
2000
		$day_name = $initial ? $wp_locale->get_weekday_initial( $wd ) : $wp_locale->get_weekday_abbrev( $wd );
2001
		$wd = esc_attr( $wd );
2002
		$calendar_output .= "\n\t\t<th scope=\"col\" title=\"$wd\">$day_name</th>";
2003
	}
2004
2005
	$calendar_output .= '
2006
	</tr>
2007
	</thead>
2008
2009
	<tfoot>
2010
	<tr>';
2011
2012 View Code Duplication
	if ( $previous ) {
2013
		$calendar_output .= "\n\t\t".'<td colspan="3" id="prev"><a href="' . get_month_link( $previous->year, $previous->month ) . '">&laquo; ' .
2014
			$wp_locale->get_month_abbrev( $wp_locale->get_month( $previous->month ) ) .
2015
		'</a></td>';
2016
	} else {
2017
		$calendar_output .= "\n\t\t".'<td colspan="3" id="prev" class="pad">&nbsp;</td>';
2018
	}
2019
2020
	$calendar_output .= "\n\t\t".'<td class="pad">&nbsp;</td>';
2021
2022 View Code Duplication
	if ( $next ) {
2023
		$calendar_output .= "\n\t\t".'<td colspan="3" id="next"><a href="' . get_month_link( $next->year, $next->month ) . '">' .
2024
			$wp_locale->get_month_abbrev( $wp_locale->get_month( $next->month ) ) .
2025
		' &raquo;</a></td>';
2026
	} else {
2027
		$calendar_output .= "\n\t\t".'<td colspan="3" id="next" class="pad">&nbsp;</td>';
2028
	}
2029
2030
	$calendar_output .= '
2031
	</tr>
2032
	</tfoot>
2033
2034
	<tbody>
2035
	<tr>';
2036
2037
	$daywithpost = array();
2038
2039
	// Get days with posts
2040
	$dayswithposts = $wpdb->get_results("SELECT DISTINCT DAYOFMONTH(post_date)
2041
		FROM $wpdb->posts WHERE post_date >= '{$thisyear}-{$thismonth}-01 00:00:00'
2042
		AND post_type = 'post' AND post_status = 'publish'
2043
		AND post_date <= '{$thisyear}-{$thismonth}-{$last_day} 23:59:59'", ARRAY_N);
2044
	if ( $dayswithposts ) {
2045
		foreach ( (array) $dayswithposts as $daywith ) {
2046
			$daywithpost[] = $daywith[0];
2047
		}
2048
	}
2049
2050
	// See how much we should pad in the beginning
2051
	$pad = calendar_week_mod( date( 'w', $unixmonth ) - $week_begins );
2052
	if ( 0 != $pad ) {
2053
		$calendar_output .= "\n\t\t".'<td colspan="'. esc_attr( $pad ) .'" class="pad">&nbsp;</td>';
2054
	}
2055
2056
	$newrow = false;
2057
	$daysinmonth = (int) date( 't', $unixmonth );
2058
2059
	for ( $day = 1; $day <= $daysinmonth; ++$day ) {
2060
		if ( isset($newrow) && $newrow ) {
2061
			$calendar_output .= "\n\t</tr>\n\t<tr>\n\t\t";
2062
		}
2063
		$newrow = false;
2064
2065
		if ( $day == gmdate( 'j', $ts ) &&
2066
			$thismonth == gmdate( 'm', $ts ) &&
2067
			$thisyear == gmdate( 'Y', $ts ) ) {
2068
			$calendar_output .= '<td id="today">';
2069
		} else {
2070
			$calendar_output .= '<td>';
2071
		}
2072
2073
		if ( in_array( $day, $daywithpost ) ) {
2074
			// any posts today?
2075
			$date_format = date( _x( 'F j, Y', 'daily archives date format' ), strtotime( "{$thisyear}-{$thismonth}-{$day}" ) );
2076
			/* translators: Post calendar label. 1: Date */
2077
			$label = sprintf( __( 'Posts published on %s' ), $date_format );
2078
			$calendar_output .= sprintf(
2079
				'<a href="%s" aria-label="%s">%s</a>',
2080
				get_day_link( $thisyear, $thismonth, $day ),
2081
				esc_attr( $label ),
2082
				$day
2083
			);
2084
		} else {
2085
			$calendar_output .= $day;
2086
		}
2087
		$calendar_output .= '</td>';
2088
2089
		if ( 6 == calendar_week_mod( date( 'w', mktime(0, 0 , 0, $thismonth, $day, $thisyear ) ) - $week_begins ) ) {
2090
			$newrow = true;
2091
		}
2092
	}
2093
2094
	$pad = 7 - calendar_week_mod( date( 'w', mktime( 0, 0 , 0, $thismonth, $day, $thisyear ) ) - $week_begins );
2095
	if ( $pad != 0 && $pad != 7 ) {
2096
		$calendar_output .= "\n\t\t".'<td class="pad" colspan="'. esc_attr( $pad ) .'">&nbsp;</td>';
2097
	}
2098
	$calendar_output .= "\n\t</tr>\n\t</tbody>\n\t</table>";
2099
2100
	$cache[ $key ] = $calendar_output;
2101
	wp_cache_set( 'get_calendar', $cache, 'calendar' );
2102
2103
	if ( $echo ) {
2104
		/**
2105
		 * Filters the HTML calendar output.
2106
		 *
2107
		 * @since 3.0.0
2108
		 *
2109
		 * @param string $calendar_output HTML output of the calendar.
2110
		 */
2111
		echo apply_filters( 'get_calendar', $calendar_output );
2112
		return;
2113
	}
2114
	/** This filter is documented in wp-includes/general-template.php */
2115
	return apply_filters( 'get_calendar', $calendar_output );
2116
}
2117
2118
/**
2119
 * Purge the cached results of get_calendar.
2120
 *
2121
 * @see get_calendar
2122
 * @since 2.1.0
2123
 */
2124
function delete_get_calendar_cache() {
2125
	wp_cache_delete( 'get_calendar', 'calendar' );
2126
}
2127
2128
/**
2129
 * Display all of the allowed tags in HTML format with attributes.
2130
 *
2131
 * This is useful for displaying in the comment area, which elements and
2132
 * attributes are supported. As well as any plugins which want to display it.
2133
 *
2134
 * @since 1.0.1
2135
 *
2136
 * @global array $allowedtags
2137
 *
2138
 * @return string HTML allowed tags entity encoded.
2139
 */
2140
function allowed_tags() {
2141
	global $allowedtags;
2142
	$allowed = '';
2143
	foreach ( (array) $allowedtags as $tag => $attributes ) {
2144
		$allowed .= '<'.$tag;
2145
		if ( 0 < count($attributes) ) {
2146
			foreach ( $attributes as $attribute => $limits ) {
2147
				$allowed .= ' '.$attribute.'=""';
2148
			}
2149
		}
2150
		$allowed .= '> ';
2151
	}
2152
	return htmlentities( $allowed );
2153
}
2154
2155
/***** Date/Time tags *****/
2156
2157
/**
2158
 * Outputs the date in iso8601 format for xml files.
2159
 *
2160
 * @since 1.0.0
2161
 */
2162
function the_date_xml() {
2163
	echo mysql2date( 'Y-m-d', get_post()->post_date, false );
2164
}
2165
2166
/**
2167
 * Display or Retrieve the date the current post was written (once per date)
2168
 *
2169
 * Will only output the date if the current post's date is different from the
2170
 * previous one output.
2171
 *
2172
 * i.e. Only one date listing will show per day worth of posts shown in the loop, even if the
2173
 * function is called several times for each post.
2174
 *
2175
 * HTML output can be filtered with 'the_date'.
2176
 * Date string output can be filtered with 'get_the_date'.
2177
 *
2178
 * @since 0.71
2179
 *
2180
 * @global string|int|bool $currentday
2181
 * @global string|int|bool $previousday
2182
 *
2183
 * @param string $d      Optional. PHP date format defaults to the date_format option if not specified.
2184
 * @param string $before Optional. Output before the date.
2185
 * @param string $after  Optional. Output after the date.
2186
 * @param bool   $echo   Optional, default is display. Whether to echo the date or return it.
2187
 * @return string|void String if retrieving.
2188
 */
2189
function the_date( $d = '', $before = '', $after = '', $echo = true ) {
2190
	global $currentday, $previousday;
2191
2192
	if ( is_new_day() ) {
2193
		$the_date = $before . get_the_date( $d ) . $after;
2194
		$previousday = $currentday;
2195
2196
		/**
2197
		 * Filters the date a post was published for display.
2198
		 *
2199
		 * @since 0.71
2200
		 *
2201
		 * @param string $the_date The formatted date string.
2202
		 * @param string $d        PHP date format. Defaults to 'date_format' option
2203
		 *                         if not specified.
2204
		 * @param string $before   HTML output before the date.
2205
		 * @param string $after    HTML output after the date.
2206
		 */
2207
		$the_date = apply_filters( 'the_date', $the_date, $d, $before, $after );
2208
2209
		if ( $echo )
2210
			echo $the_date;
2211
		else
2212
			return $the_date;
2213
	}
2214
}
2215
2216
/**
2217
 * Retrieve the date on which the post was written.
2218
 *
2219
 * Unlike the_date() this function will always return the date.
2220
 * Modify output with the {@see 'get_the_date'} filter.
2221
 *
2222
 * @since 3.0.0
2223
 *
2224
 * @param  string      $d    Optional. PHP date format defaults to the date_format option if not specified.
2225
 * @param  int|WP_Post $post Optional. Post ID or WP_Post object. Default current post.
2226
 * @return false|string Date the current post was written. False on failure.
2227
 */
2228
function get_the_date( $d = '', $post = null ) {
2229
	$post = get_post( $post );
2230
2231
	if ( ! $post ) {
2232
		return false;
2233
	}
2234
2235 View Code Duplication
	if ( '' == $d ) {
2236
		$the_date = mysql2date( get_option( 'date_format' ), $post->post_date );
2237
	} else {
2238
		$the_date = mysql2date( $d, $post->post_date );
2239
	}
2240
2241
	/**
2242
	 * Filters the date a post was published.
2243
	 *
2244
	 * @since 3.0.0
2245
	 *
2246
	 * @param string      $the_date The formatted date.
2247
	 * @param string      $d        PHP date format. Defaults to 'date_format' option
2248
	 *                              if not specified.
2249
	 * @param int|WP_Post $post     The post object or ID.
2250
	 */
2251
	return apply_filters( 'get_the_date', $the_date, $d, $post );
2252
}
2253
2254
/**
2255
 * Display the date on which the post was last modified.
2256
 *
2257
 * @since 2.1.0
2258
 *
2259
 * @param string $d      Optional. PHP date format defaults to the date_format option if not specified.
2260
 * @param string $before Optional. Output before the date.
2261
 * @param string $after  Optional. Output after the date.
2262
 * @param bool   $echo   Optional, default is display. Whether to echo the date or return it.
2263
 * @return string|void String if retrieving.
2264
 */
2265
function the_modified_date( $d = '', $before = '', $after = '', $echo = true ) {
2266
	$the_modified_date = $before . get_the_modified_date($d) . $after;
2267
2268
	/**
2269
	 * Filters the date a post was last modified for display.
2270
	 *
2271
	 * @since 2.1.0
2272
	 *
2273
	 * @param string $the_modified_date The last modified date.
2274
	 * @param string $d                 PHP date format. Defaults to 'date_format' option
2275
	 *                                  if not specified.
2276
	 * @param string $before            HTML output before the date.
2277
	 * @param string $after             HTML output after the date.
2278
	 */
2279
	$the_modified_date = apply_filters( 'the_modified_date', $the_modified_date, $d, $before, $after );
2280
2281
	if ( $echo )
2282
		echo $the_modified_date;
2283
	else
2284
		return $the_modified_date;
2285
2286
}
2287
2288
/**
2289
 * Retrieve the date on which the post was last modified.
2290
 *
2291
 * @since 2.1.0
2292
 * @since 4.6.0 Added the `$post` parameter.
2293
 *
2294
 * @param string      $d    Optional. PHP date format defaults to the date_format option if not specified.
2295
 * @param int|WP_Post $post Optional. Post ID or WP_Post object. Default current post.
2296
 * @return false|string Date the current post was modified. False on failure.
2297
 */
2298 View Code Duplication
function get_the_modified_date( $d = '', $post = null ) {
0 ignored issues
show
This function seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
2299
	$post = get_post( $post );
2300
2301
	if ( ! $post ) {
2302
		// For backward compatibility, failures go through the filter below.
2303
		$the_time = false;
2304
	} elseif ( empty( $d ) ) {
2305
		$the_time = get_post_modified_time( get_option( 'date_format' ), false, $post, true );
2306
	} else {
2307
		$the_time = get_post_modified_time( $d, false, $post, true );
2308
	}
2309
2310
	/**
2311
	 * Filters the date a post was last modified.
2312
	 *
2313
	 * @since 2.1.0
2314
	 * @since 4.6.0 Added the `$post` parameter.
2315
	 *
2316
	 * @param string  $the_time The formatted date.
2317
	 * @param string  $d        PHP date format. Defaults to value specified in
2318
	 *                          'date_format' option.
2319
	 * @param WP_Post $post     WP_Post object.
2320
	 */
2321
	return apply_filters( 'get_the_modified_date', $the_time, $d, $post );
2322
}
2323
2324
/**
2325
 * Display the time at which the post was written.
2326
 *
2327
 * @since 0.71
2328
 *
2329
 * @param string $d Either 'G', 'U', or php date format.
2330
 */
2331
function the_time( $d = '' ) {
2332
	/**
2333
	 * Filters the time a post was written for display.
2334
	 *
2335
	 * @since 0.71
2336
	 *
2337
	 * @param string $get_the_time The formatted time.
2338
	 * @param string $d            The time format. Accepts 'G', 'U',
2339
	 *                             or php date format.
2340
	 */
2341
	echo apply_filters( 'the_time', get_the_time( $d ), $d );
2342
}
2343
2344
/**
2345
 * Retrieve the time at which the post was written.
2346
 *
2347
 * @since 1.5.0
2348
 *
2349
 * @param string      $d    Optional. Format to use for retrieving the time the post
2350
 *                          was written. Either 'G', 'U', or php date format defaults
2351
 *                          to the value specified in the time_format option. Default empty.
2352
 * @param int|WP_Post $post WP_Post object or ID. Default is global $post object.
2353
 * @return string|int|false Formatted date string or Unix timestamp if `$id` is 'U' or 'G'. False on failure.
2354
 */
2355 View Code Duplication
function get_the_time( $d = '', $post = null ) {
0 ignored issues
show
This function seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
2356
	$post = get_post($post);
2357
2358
	if ( ! $post ) {
2359
		return false;
2360
	}
2361
2362
	if ( '' == $d )
2363
		$the_time = get_post_time(get_option('time_format'), false, $post, true);
2364
	else
2365
		$the_time = get_post_time($d, false, $post, true);
2366
2367
	/**
2368
	 * Filters the time a post was written.
2369
	 *
2370
	 * @since 1.5.0
2371
	 *
2372
	 * @param string      $the_time The formatted time.
2373
	 * @param string      $d        Format to use for retrieving the time the post was written.
2374
	 *                              Accepts 'G', 'U', or php date format value specified
2375
	 *                              in 'time_format' option. Default empty.
2376
	 * @param int|WP_Post $post     WP_Post object or ID.
2377
	 */
2378
	return apply_filters( 'get_the_time', $the_time, $d, $post );
2379
}
2380
2381
/**
2382
 * Retrieve the time at which the post was written.
2383
 *
2384
 * @since 2.0.0
2385
 *
2386
 * @param string      $d         Optional. Format to use for retrieving the time the post
2387
 *                               was written. Either 'G', 'U', or php date format. Default 'U'.
2388
 * @param bool        $gmt       Optional. Whether to retrieve the GMT time. Default false.
2389
 * @param int|WP_Post $post      WP_Post object or ID. Default is global $post object.
2390
 * @param bool        $translate Whether to translate the time string. Default false.
2391
 * @return string|int|false Formatted date string or Unix timestamp if `$id` is 'U' or 'G'. False on failure.
2392
 */
2393 View Code Duplication
function get_post_time( $d = 'U', $gmt = false, $post = null, $translate = false ) {
0 ignored issues
show
This function seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
2394
	$post = get_post($post);
2395
2396
	if ( ! $post ) {
2397
		return false;
2398
	}
2399
2400
	if ( $gmt )
2401
		$time = $post->post_date_gmt;
2402
	else
2403
		$time = $post->post_date;
2404
2405
	$time = mysql2date($d, $time, $translate);
2406
2407
	/**
2408
	 * Filters the localized time a post was written.
2409
	 *
2410
	 * @since 2.6.0
2411
	 *
2412
	 * @param string $time The formatted time.
2413
	 * @param string $d    Format to use for retrieving the time the post was written.
2414
	 *                     Accepts 'G', 'U', or php date format. Default 'U'.
2415
	 * @param bool   $gmt  Whether to retrieve the GMT time. Default false.
2416
	 */
2417
	return apply_filters( 'get_post_time', $time, $d, $gmt );
2418
}
2419
2420
/**
2421
 * Display the time at which the post was last modified.
2422
 *
2423
 * @since 2.0.0
2424
 *
2425
 * @param string $d Optional Either 'G', 'U', or php date format defaults to the value specified in the time_format option.
2426
 */
2427
function the_modified_time($d = '') {
2428
	/**
2429
	 * Filters the localized time a post was last modified, for display.
2430
	 *
2431
	 * @since 2.0.0
2432
	 *
2433
	 * @param string $get_the_modified_time The formatted time.
2434
	 * @param string $d                     The time format. Accepts 'G', 'U',
2435
	 *                                      or php date format. Defaults to value
2436
	 *                                      specified in 'time_format' option.
2437
	 */
2438
	echo apply_filters( 'the_modified_time', get_the_modified_time($d), $d );
2439
}
2440
2441
/**
2442
 * Retrieve the time at which the post was last modified.
2443
 *
2444
 * @since 2.0.0
2445
 * @since 4.6.0 Added the `$post` parameter.
2446
 *
2447
 * @param string      $d     Optional. Format to use for retrieving the time the post
2448
 *                           was modified. Either 'G', 'U', or php date format defaults
2449
 *                           to the value specified in the time_format option. Default empty.
2450
 * @param int|WP_Post $post  Optional. Post ID or WP_Post object. Default current post.
2451
 * @return false|string Formatted date string or Unix timestamp. False on failure.
2452
 */
2453 View Code Duplication
function get_the_modified_time( $d = '', $post = null ) {
0 ignored issues
show
This function seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
2454
	$post = get_post( $post );
2455
2456
	if ( ! $post ) {
2457
		// For backward compatibility, failures go through the filter below.
2458
		$the_time = false;
2459
	} elseif ( empty( $d ) ) {
2460
		$the_time = get_post_modified_time( get_option( 'time_format' ), false, $post, true );
2461
	} else {
2462
		$the_time = get_post_modified_time( $d, false, $post, true );
2463
	}
2464
2465
	/**
2466
	 * Filters the localized time a post was last modified.
2467
	 *
2468
	 * @since 2.0.0
2469
	 * @since 4.6.0 Added the `$post` parameter.
2470
	 *
2471
	 * @param string $the_time The formatted time.
2472
	 * @param string $d        Format to use for retrieving the time the post was
2473
	 *                         written. Accepts 'G', 'U', or php date format. Defaults
2474
	 *                         to value specified in 'time_format' option.
2475
	 * @param WP_Post $post    WP_Post object.
2476
	 */
2477
	return apply_filters( 'get_the_modified_time', $the_time, $d, $post );
2478
}
2479
2480
/**
2481
 * Retrieve the time at which the post was last modified.
2482
 *
2483
 * @since 2.0.0
2484
 *
2485
 * @param string      $d         Optional. Format to use for retrieving the time the post
2486
 *                               was modified. Either 'G', 'U', or php date format. Default 'U'.
2487
 * @param bool        $gmt       Optional. Whether to retrieve the GMT time. Default false.
2488
 * @param int|WP_Post $post      WP_Post object or ID. Default is global $post object.
2489
 * @param bool        $translate Whether to translate the time string. Default false.
2490
 * @return string|int|false Formatted date string or Unix timestamp if `$id` is 'U' or 'G'. False on failure.
2491
 */
2492 View Code Duplication
function get_post_modified_time( $d = 'U', $gmt = false, $post = null, $translate = false ) {
0 ignored issues
show
This function seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
2493
	$post = get_post($post);
2494
2495
	if ( ! $post ) {
2496
		return false;
2497
	}
2498
2499
	if ( $gmt )
2500
		$time = $post->post_modified_gmt;
2501
	else
2502
		$time = $post->post_modified;
2503
	$time = mysql2date($d, $time, $translate);
2504
2505
	/**
2506
	 * Filters the localized time a post was last modified.
2507
	 *
2508
	 * @since 2.8.0
2509
	 *
2510
	 * @param string $time The formatted time.
2511
	 * @param string $d    The date format. Accepts 'G', 'U', or php date format. Default 'U'.
2512
	 * @param bool   $gmt  Whether to return the GMT time. Default false.
2513
	 */
2514
	return apply_filters( 'get_post_modified_time', $time, $d, $gmt );
2515
}
2516
2517
/**
2518
 * Display the weekday on which the post was written.
2519
 *
2520
 * @since 0.71
2521
 *
2522
 * @global WP_Locale $wp_locale
2523
 */
2524
function the_weekday() {
2525
	global $wp_locale;
2526
	$the_weekday = $wp_locale->get_weekday( mysql2date( 'w', get_post()->post_date, false ) );
2527
2528
	/**
2529
	 * Filters the weekday on which the post was written, for display.
2530
	 *
2531
	 * @since 0.71
2532
	 *
2533
	 * @param string $the_weekday
2534
	 */
2535
	echo apply_filters( 'the_weekday', $the_weekday );
2536
}
2537
2538
/**
2539
 * Display the weekday on which the post was written.
2540
 *
2541
 * Will only output the weekday if the current post's weekday is different from
2542
 * the previous one output.
2543
 *
2544
 * @since 0.71
2545
 *
2546
 * @global WP_Locale       $wp_locale
2547
 * @global string|int|bool $currentday
2548
 * @global string|int|bool $previousweekday
2549
 *
2550
 * @param string $before Optional Output before the date.
2551
 * @param string $after Optional Output after the date.
2552
 */
2553
function the_weekday_date($before='',$after='') {
2554
	global $wp_locale, $currentday, $previousweekday;
2555
	$the_weekday_date = '';
2556
	if ( $currentday != $previousweekday ) {
2557
		$the_weekday_date .= $before;
2558
		$the_weekday_date .= $wp_locale->get_weekday( mysql2date( 'w', get_post()->post_date, false ) );
2559
		$the_weekday_date .= $after;
2560
		$previousweekday = $currentday;
2561
	}
2562
2563
	/**
2564
	 * Filters the localized date on which the post was written, for display.
2565
	 *
2566
	 * @since 0.71
2567
	 *
2568
	 * @param string $the_weekday_date
2569
	 * @param string $before           The HTML to output before the date.
2570
	 * @param string $after            The HTML to output after the date.
2571
	 */
2572
	$the_weekday_date = apply_filters( 'the_weekday_date', $the_weekday_date, $before, $after );
2573
	echo $the_weekday_date;
2574
}
2575
2576
/**
2577
 * Fire the wp_head action.
2578
 *
2579
 * See {@see 'wp_head'}.
2580
 *
2581
 * @since 1.2.0
2582
 */
2583
function wp_head() {
2584
	/**
2585
	 * Prints scripts or data in the head tag on the front end.
2586
	 *
2587
	 * @since 1.5.0
2588
	 */
2589
	do_action( 'wp_head' );
2590
}
2591
2592
/**
2593
 * Fire the wp_footer action.
2594
 *
2595
 * See {@see 'wp_footer'}.
2596
 *
2597
 * @since 1.5.1
2598
 */
2599
function wp_footer() {
2600
	/**
2601
	 * Prints scripts or data before the closing body tag on the front end.
2602
	 *
2603
	 * @since 1.5.1
2604
	 */
2605
	do_action( 'wp_footer' );
2606
}
2607
2608
/**
2609
 * Display the links to the general feeds.
2610
 *
2611
 * @since 2.8.0
2612
 *
2613
 * @param array $args Optional arguments.
2614
 */
2615
function feed_links( $args = array() ) {
2616
	if ( !current_theme_supports('automatic-feed-links') )
2617
		return;
2618
2619
	$defaults = array(
2620
		/* translators: Separator between blog name and feed type in feed links */
2621
		'separator'	=> _x('&raquo;', 'feed link'),
2622
		/* translators: 1: blog title, 2: separator (raquo) */
2623
		'feedtitle'	=> __('%1$s %2$s Feed'),
2624
		/* translators: 1: blog title, 2: separator (raquo) */
2625
		'comstitle'	=> __('%1$s %2$s Comments Feed'),
2626
	);
2627
2628
	$args = wp_parse_args( $args, $defaults );
2629
2630
	/**
2631
	 * Filters whether to display the posts feed link.
2632
	 *
2633
	 * @since 4.4.0
2634
	 *
2635
	 * @param bool $show Whether to display the posts feed link. Default true.
2636
	 */
2637 View Code Duplication
	if ( apply_filters( 'feed_links_show_posts_feed', true ) ) {
2638
		echo '<link rel="alternate" type="' . feed_content_type() . '" title="' . esc_attr( sprintf( $args['feedtitle'], get_bloginfo( 'name' ), $args['separator'] ) ) . '" href="' . esc_url( get_feed_link() ) . "\" />\n";
2639
	}
2640
2641
	/**
2642
	 * Filters whether to display the comments feed link.
2643
	 *
2644
	 * @since 4.4.0
2645
	 *
2646
	 * @param bool $show Whether to display the comments feed link. Default true.
2647
	 */
2648 View Code Duplication
	if ( apply_filters( 'feed_links_show_comments_feed', true ) ) {
2649
		echo '<link rel="alternate" type="' . feed_content_type() . '" title="' . esc_attr( sprintf( $args['comstitle'], get_bloginfo( 'name' ), $args['separator'] ) ) . '" href="' . esc_url( get_feed_link( 'comments_' . get_default_feed() ) ) . "\" />\n";
2650
	}
2651
}
2652
2653
/**
2654
 * Display the links to the extra feeds such as category feeds.
2655
 *
2656
 * @since 2.8.0
2657
 *
2658
 * @param array $args Optional arguments.
2659
 */
2660
function feed_links_extra( $args = array() ) {
2661
	$defaults = array(
2662
		/* translators: Separator between blog name and feed type in feed links */
2663
		'separator'   => _x('&raquo;', 'feed link'),
2664
		/* translators: 1: blog name, 2: separator(raquo), 3: post title */
2665
		'singletitle' => __('%1$s %2$s %3$s Comments Feed'),
2666
		/* translators: 1: blog name, 2: separator(raquo), 3: category name */
2667
		'cattitle'    => __('%1$s %2$s %3$s Category Feed'),
2668
		/* translators: 1: blog name, 2: separator(raquo), 3: tag name */
2669
		'tagtitle'    => __('%1$s %2$s %3$s Tag Feed'),
2670
		/* translators: 1: blog name, 2: separator(raquo), 3: term name, 4: taxonomy singular name */
2671
		'taxtitle'    => __('%1$s %2$s %3$s %4$s Feed'),
2672
		/* translators: 1: blog name, 2: separator(raquo), 3: author name  */
2673
		'authortitle' => __('%1$s %2$s Posts by %3$s Feed'),
2674
		/* translators: 1: blog name, 2: separator(raquo), 3: search phrase */
2675
		'searchtitle' => __('%1$s %2$s Search Results for &#8220;%3$s&#8221; Feed'),
2676
		/* translators: 1: blog name, 2: separator(raquo), 3: post type name */
2677
		'posttypetitle' => __('%1$s %2$s %3$s Feed'),
2678
	);
2679
2680
	$args = wp_parse_args( $args, $defaults );
2681
2682
	if ( is_singular() ) {
2683
		$id = 0;
2684
		$post = get_post( $id );
2685
2686
		if ( comments_open() || pings_open() || $post->comment_count > 0 ) {
2687
			$title = sprintf( $args['singletitle'], get_bloginfo('name'), $args['separator'], the_title_attribute( array( 'echo' => false ) ) );
2688
			$href = get_post_comments_feed_link( $post->ID );
2689
		}
2690
	} elseif ( is_post_type_archive() ) {
2691
		$post_type = get_query_var( 'post_type' );
2692
		if ( is_array( $post_type ) )
2693
			$post_type = reset( $post_type );
2694
2695
		$post_type_obj = get_post_type_object( $post_type );
2696
		$title = sprintf( $args['posttypetitle'], get_bloginfo( 'name' ), $args['separator'], $post_type_obj->labels->name );
2697
		$href = get_post_type_archive_feed_link( $post_type_obj->name );
2698
	} elseif ( is_category() ) {
2699
		$term = get_queried_object();
2700
2701 View Code Duplication
		if ( $term ) {
2702
			$title = sprintf( $args['cattitle'], get_bloginfo('name'), $args['separator'], $term->name );
2703
			$href = get_category_feed_link( $term->term_id );
2704
		}
2705
	} elseif ( is_tag() ) {
2706
		$term = get_queried_object();
2707
2708 View Code Duplication
		if ( $term ) {
2709
			$title = sprintf( $args['tagtitle'], get_bloginfo('name'), $args['separator'], $term->name );
2710
			$href = get_tag_feed_link( $term->term_id );
2711
		}
2712
	} elseif ( is_tax() ) {
2713
 		$term = get_queried_object();
2714
 		$tax = get_taxonomy( $term->taxonomy );
2715
 		$title = sprintf( $args['taxtitle'], get_bloginfo('name'), $args['separator'], $term->name, $tax->labels->singular_name );
2716
 		$href = get_term_feed_link( $term->term_id, $term->taxonomy );
2717
	} elseif ( is_author() ) {
2718
		$author_id = intval( get_query_var('author') );
2719
2720
		$title = sprintf( $args['authortitle'], get_bloginfo('name'), $args['separator'], get_the_author_meta( 'display_name', $author_id ) );
2721
		$href = get_author_feed_link( $author_id );
2722
	} elseif ( is_search() ) {
2723
		$title = sprintf( $args['searchtitle'], get_bloginfo('name'), $args['separator'], get_search_query( false ) );
2724
		$href = get_search_feed_link();
2725
	} elseif ( is_post_type_archive() ) {
2726
		$title = sprintf( $args['posttypetitle'], get_bloginfo('name'), $args['separator'], post_type_archive_title( '', false ) );
2727
		$post_type_obj = get_queried_object();
2728
		if ( $post_type_obj )
2729
			$href = get_post_type_archive_feed_link( $post_type_obj->name );
2730
	}
2731
2732
	if ( isset($title) && isset($href) )
2733
		echo '<link rel="alternate" type="' . feed_content_type() . '" title="' . esc_attr( $title ) . '" href="' . esc_url( $href ) . '" />' . "\n";
0 ignored issues
show
It seems like $href can also be of type false; however, esc_url() does only seem to accept string, did you maybe forget to handle an error condition?
Loading history...
2734
}
2735
2736
/**
2737
 * Display the link to the Really Simple Discovery service endpoint.
2738
 *
2739
 * @link http://archipelago.phrasewise.com/rsd
2740
 * @since 2.0.0
2741
 */
2742
function rsd_link() {
2743
	echo '<link rel="EditURI" type="application/rsd+xml" title="RSD" href="' . esc_url( site_url( 'xmlrpc.php?rsd', 'rpc' ) ) . '" />' . "\n";
2744
}
2745
2746
/**
2747
 * Display the link to the Windows Live Writer manifest file.
2748
 *
2749
 * @link https://msdn.microsoft.com/en-us/library/bb463265.aspx
2750
 * @since 2.3.1
2751
 */
2752
function wlwmanifest_link() {
2753
	echo '<link rel="wlwmanifest" type="application/wlwmanifest+xml" href="',
2754
		includes_url( 'wlwmanifest.xml' ), '" /> ', "\n";
2755
}
2756
2757
/**
2758
 * Displays a noindex meta tag if required by the blog configuration.
2759
 *
2760
 * If a blog is marked as not being public then the noindex meta tag will be
2761
 * output to tell web robots not to index the page content. Add this to the
2762
 * {@see 'wp_head'} action.
2763
 *
2764
 * Typical usage is as a {@see 'wp_head'} callback:
2765
 *
2766
 *     add_action( 'wp_head', 'noindex' );
2767
 *
2768
 * @see wp_no_robots
2769
 *
2770
 * @since 2.1.0
2771
 */
2772
function noindex() {
2773
	// If the blog is not public, tell robots to go away.
2774
	if ( '0' == get_option('blog_public') )
2775
		wp_no_robots();
2776
}
2777
2778
/**
2779
 * Display a noindex meta tag.
2780
 *
2781
 * Outputs a noindex meta tag that tells web robots not to index the page content.
2782
 * Typical usage is as a wp_head callback. add_action( 'wp_head', 'wp_no_robots' );
2783
 *
2784
 * @since 3.3.0
2785
 */
2786
function wp_no_robots() {
2787
	echo "<meta name='robots' content='noindex,follow' />\n";
2788
}
2789
2790
/**
2791
 * Display site icon meta tags.
2792
 *
2793
 * @since 4.3.0
2794
 *
2795
 * @link https://www.whatwg.org/specs/web-apps/current-work/multipage/links.html#rel-icon HTML5 specification link icon.
2796
 */
2797
function wp_site_icon() {
2798
	if ( ! has_site_icon() && ! is_customize_preview() ) {
2799
		return;
2800
	}
2801
2802
	$meta_tags = array();
2803
	$icon_32 = get_site_icon_url( 32 );
2804
	if ( empty( $icon_32 ) && is_customize_preview() ) {
2805
		$icon_32 = '/favicon.ico'; // Serve default favicon URL in customizer so element can be updated for preview.
2806
	}
2807
	if ( $icon_32 ) {
2808
		$meta_tags[] = sprintf( '<link rel="icon" href="%s" sizes="32x32" />', esc_url( $icon_32 ) );
2809
	}
2810
	$icon_192 = get_site_icon_url( 192 );
2811
	if ( $icon_192 ) {
2812
		$meta_tags[] = sprintf( '<link rel="icon" href="%s" sizes="192x192" />', esc_url( $icon_192 ) );
2813
	}
2814
	$icon_180 = get_site_icon_url( 180 );
2815
	if ( $icon_180 ) {
2816
		$meta_tags[] = sprintf( '<link rel="apple-touch-icon-precomposed" href="%s" />', esc_url( $icon_180 ) );
2817
	}
2818
	$icon_270 = get_site_icon_url( 270 );
2819
	if ( $icon_270 ) {
2820
		$meta_tags[] = sprintf( '<meta name="msapplication-TileImage" content="%s" />', esc_url( $icon_270 ) );
2821
	}
2822
2823
	/**
2824
	 * Filters the site icon meta tags, so Plugins can add their own.
2825
	 *
2826
	 * @since 4.3.0
2827
	 *
2828
	 * @param array $meta_tags Site Icon meta elements.
2829
	 */
2830
	$meta_tags = apply_filters( 'site_icon_meta_tags', $meta_tags );
2831
	$meta_tags = array_filter( $meta_tags );
2832
2833
	foreach ( $meta_tags as $meta_tag ) {
2834
		echo "$meta_tag\n";
2835
	}
2836
}
2837
2838
/**
2839
 * Prints resource hints to browsers for pre-fetching, pre-rendering
2840
 * and pre-connecting to web sites.
2841
 *
2842
 * Gives hints to browsers to prefetch specific pages or render them
2843
 * in the background, to perform DNS lookups or to begin the connection
2844
 * handshake (DNS, TCP, TLS) in the background.
2845
 *
2846
 * These performance improving indicators work by using `<link rel"…">`.
2847
 *
2848
 * @since 4.6.0
2849
 */
2850
function wp_resource_hints() {
2851
	$hints = array(
2852
		'dns-prefetch' => wp_dependencies_unique_hosts(),
2853
		'preconnect'   => array(),
2854
		'prefetch'     => array(),
2855
		'prerender'    => array(),
2856
	);
2857
2858
	/*
2859
	 * Add DNS prefetch for the Emoji CDN.
2860
	 * The path is removed in the foreach loop below.
2861
	 */
2862
	/** This filter is documented in wp-includes/formatting.php */
2863
	$hints['dns-prefetch'][] = apply_filters( 'emoji_svg_url', 'https://s.w.org/images/core/emoji/2.3/svg/' );
2864
2865
	foreach ( $hints as $relation_type => $urls ) {
2866
		$unique_urls = array();
2867
2868
		/**
2869
		 * Filters domains and URLs for resource hints of relation type.
2870
		 *
2871
		 * @since 4.6.0
2872
		 *
2873
		 * @param array  $urls          URLs to print for resource hints.
2874
		 * @param string $relation_type The relation type the URLs are printed for, e.g. 'preconnect' or 'prerender'.
2875
		 */
2876
		$urls = apply_filters( 'wp_resource_hints', $urls, $relation_type );
2877
2878
		foreach ( $urls as $key => $url ) {
2879
			$atts = array();
2880
2881
			if ( is_array( $url ) ) {
2882
				if ( isset( $url['href'] ) ) {
2883
					$atts = $url;
2884
					$url  = $url['href'];
2885
				} else {
2886
					continue;
2887
				}
2888
			}
2889
2890
			$url = esc_url( $url, array( 'http', 'https' ) );
2891
2892
			if ( ! $url ) {
2893
				continue;
2894
			}
2895
2896
			if ( isset( $unique_urls[ $url ] ) ) {
2897
				continue;
2898
			}
2899
2900
			if ( in_array( $relation_type, array( 'preconnect', 'dns-prefetch' ) ) ) {
2901
				$parsed = wp_parse_url( $url );
2902
2903
				if ( empty( $parsed['host'] ) ) {
2904
					continue;
2905
				}
2906
2907
				if ( 'preconnect' === $relation_type && ! empty( $parsed['scheme'] ) ) {
2908
					$url = $parsed['scheme'] . '://' . $parsed['host'];
2909
				} else {
2910
					// Use protocol-relative URLs for dns-prefetch or if scheme is missing.
2911
					$url = '//' . $parsed['host'];
2912
				}
2913
			}
2914
2915
			$atts['rel'] = $relation_type;
2916
			$atts['href'] = $url;
2917
2918
			$unique_urls[ $url ] = $atts;
2919
		}
2920
2921
		foreach ( $unique_urls as $atts ) {
2922
			$html = '';
2923
2924
			foreach ( $atts as $attr => $value ) {
2925
				if ( ! is_scalar( $value ) ||
2926
				     ( ! in_array( $attr, array( 'as', 'crossorigin', 'href', 'pr', 'rel', 'type' ), true ) && ! is_numeric( $attr ))
2927
				) {
2928
					continue;
2929
				}
2930
2931
				$value = ( 'href' === $attr ) ? esc_url( $value ) : esc_attr( $value );
2932
2933
				if ( ! is_string( $attr ) ) {
2934
					$html .= " $value";
2935
				} else {
2936
					$html .= " $attr='$value'";
2937
				}
2938
			}
2939
2940
			$html = trim( $html );
2941
2942
			echo "<link $html />\n";
2943
		}
2944
	}
2945
}
2946
2947
/**
2948
 * Retrieves a list of unique hosts of all enqueued scripts and styles.
2949
 *
2950
 * @since 4.6.0
2951
 *
2952
 * @return array A list of unique hosts of enqueued scripts and styles.
2953
 */
2954
function wp_dependencies_unique_hosts() {
2955
	global $wp_scripts, $wp_styles;
2956
2957
	$unique_hosts = array();
2958
2959
	foreach ( array( $wp_scripts, $wp_styles ) as $dependencies ) {
2960
		if ( $dependencies instanceof WP_Dependencies && ! empty( $dependencies->queue ) ) {
2961
			foreach ( $dependencies->queue as $handle ) {
2962
				if ( ! isset( $dependencies->registered[ $handle ] ) ) {
2963
					continue;
2964
				}
2965
2966
				/* @var _WP_Dependency $dependency */
2967
				$dependency = $dependencies->registered[ $handle ];
2968
				$parsed     = wp_parse_url( $dependency->src );
2969
2970
				if ( ! empty( $parsed['host'] ) && ! in_array( $parsed['host'], $unique_hosts ) && $parsed['host'] !== $_SERVER['SERVER_NAME'] ) {
2971
					$unique_hosts[] = $parsed['host'];
2972
				}
2973
			}
2974
		}
2975
	}
2976
2977
	return $unique_hosts;
2978
}
2979
2980
/**
2981
 * Whether the user can access the visual editor.
2982
 *
2983
 * Checks if the user can access the visual editor and that it's supported by the user's browser.
2984
 *
2985
 * @since 2.0.0
2986
 *
2987
 * @global bool $wp_rich_edit Whether the user can access the visual editor.
2988
 * @global bool $is_gecko     Whether the browser is Gecko-based.
2989
 * @global bool $is_opera     Whether the browser is Opera.
2990
 * @global bool $is_safari    Whether the browser is Safari.
2991
 * @global bool $is_chrome    Whether the browser is Chrome.
2992
 * @global bool $is_IE        Whether the browser is Internet Explorer.
2993
 * @global bool $is_edge      Whether the browser is Microsoft Edge.
2994
 *
2995
 * @return bool True if the user can access the visual editor, false otherwise.
2996
 */
2997
function user_can_richedit() {
2998
	global $wp_rich_edit, $is_gecko, $is_opera, $is_safari, $is_chrome, $is_IE, $is_edge;
2999
3000
	if ( !isset($wp_rich_edit) ) {
3001
		$wp_rich_edit = false;
3002
3003
		if ( get_user_option( 'rich_editing' ) == 'true' || ! is_user_logged_in() ) { // default to 'true' for logged out users
3004
			if ( $is_safari ) {
3005
				$wp_rich_edit = ! wp_is_mobile() || ( preg_match( '!AppleWebKit/(\d+)!', $_SERVER['HTTP_USER_AGENT'], $match ) && intval( $match[1] ) >= 534 );
3006
			} elseif ( $is_IE ) {
3007
				$wp_rich_edit = ( strpos( $_SERVER['HTTP_USER_AGENT'], 'MSIE ' ) === false );
3008
			} elseif ( $is_gecko || $is_chrome || $is_edge || ( $is_opera && !wp_is_mobile() ) ) {
3009
				$wp_rich_edit = true;
3010
			}
3011
		}
3012
	}
3013
3014
	/**
3015
	 * Filters whether the user can access the visual editor.
3016
	 *
3017
	 * @since 2.1.0
3018
	 *
3019
	 * @param bool $wp_rich_edit Whether the user can access the visual editor.
3020
	 */
3021
	return apply_filters( 'user_can_richedit', $wp_rich_edit );
3022
}
3023
3024
/**
3025
 * Find out which editor should be displayed by default.
3026
 *
3027
 * Works out which of the two editors to display as the current editor for a
3028
 * user. The 'html' setting is for the "Text" editor tab.
3029
 *
3030
 * @since 2.5.0
3031
 *
3032
 * @return string Either 'tinymce', or 'html', or 'test'
3033
 */
3034
function wp_default_editor() {
3035
	$r = user_can_richedit() ? 'tinymce' : 'html'; // defaults
3036
	if ( wp_get_current_user() ) { // look for cookie
3037
		$ed = get_user_setting('editor', 'tinymce');
3038
		$r = ( in_array($ed, array('tinymce', 'html', 'test') ) ) ? $ed : $r;
3039
	}
3040
3041
	/**
3042
	 * Filters which editor should be displayed by default.
3043
	 *
3044
	 * @since 2.5.0
3045
	 *
3046
	 * @param string $r Which editor should be displayed by default. Either 'tinymce', 'html', or 'test'.
3047
	 */
3048
	return apply_filters( 'wp_default_editor', $r );
3049
}
3050
3051
/**
3052
 * Renders an editor.
3053
 *
3054
 * Using this function is the proper way to output all needed components for both TinyMCE and Quicktags.
3055
 * _WP_Editors should not be used directly. See https://core.trac.wordpress.org/ticket/17144.
3056
 *
3057
 * NOTE: Once initialized the TinyMCE editor cannot be safely moved in the DOM. For that reason
3058
 * running wp_editor() inside of a meta box is not a good idea unless only Quicktags is used.
3059
 * On the post edit screen several actions can be used to include additional editors
3060
 * containing TinyMCE: 'edit_page_form', 'edit_form_advanced' and 'dbx_post_sidebar'.
3061
 * See https://core.trac.wordpress.org/ticket/19173 for more information.
3062
 *
3063
 * @see _WP_Editors::editor()
3064
 * @since 3.3.0
3065
 *
3066
 * @param string $content   Initial content for the editor.
3067
 * @param string $editor_id HTML ID attribute value for the textarea and TinyMCE. Can only be /[a-z]+/.
3068
 * @param array  $settings  See _WP_Editors::editor().
3069
 */
3070
function wp_editor( $content, $editor_id, $settings = array() ) {
3071
	if ( ! class_exists( '_WP_Editors', false ) )
3072
		require( ABSPATH . WPINC . '/class-wp-editor.php' );
3073
	_WP_Editors::editor($content, $editor_id, $settings);
3074
}
3075
3076
/**
3077
 * Outputs the editor scripts, stylesheets, and default settings.
3078
 *
3079
 * The editor can be initialized when needed after page load.
3080
 * See wp.editor.initialize() in wp-admin/js/editor.js for initialization options.
3081
 *
3082
 * @uses _WP_Editors
3083
 * @since 4.8.0
3084
 */
3085
function wp_enqueue_editor() {
3086
	if ( ! class_exists( '_WP_Editors', false ) ) {
3087
		require( ABSPATH . WPINC . '/class-wp-editor.php' );
3088
	}
3089
3090
	_WP_Editors::enqueue_default_editor();
3091
}
3092
3093
/**
3094
 * Retrieves the contents of the search WordPress query variable.
3095
 *
3096
 * The search query string is passed through esc_attr() to ensure that it is safe
3097
 * for placing in an html attribute.
3098
 *
3099
 * @since 2.3.0
3100
 *
3101
 * @param bool $escaped Whether the result is escaped. Default true.
3102
 * 	                    Only use when you are later escaping it. Do not use unescaped.
3103
 * @return string
3104
 */
3105
function get_search_query( $escaped = true ) {
3106
	/**
3107
	 * Filters the contents of the search query variable.
3108
	 *
3109
	 * @since 2.3.0
3110
	 *
3111
	 * @param mixed $search Contents of the search query variable.
3112
	 */
3113
	$query = apply_filters( 'get_search_query', get_query_var( 's' ) );
3114
3115
	if ( $escaped )
3116
		$query = esc_attr( $query );
3117
	return $query;
3118
}
3119
3120
/**
3121
 * Displays the contents of the search query variable.
3122
 *
3123
 * The search query string is passed through esc_attr() to ensure that it is safe
3124
 * for placing in an html attribute.
3125
 *
3126
 * @since 2.1.0
3127
 */
3128
function the_search_query() {
3129
	/**
3130
	 * Filters the contents of the search query variable for display.
3131
	 *
3132
	 * @since 2.3.0
3133
	 *
3134
	 * @param mixed $search Contents of the search query variable.
3135
	 */
3136
	echo esc_attr( apply_filters( 'the_search_query', get_search_query( false ) ) );
3137
}
3138
3139
/**
3140
 * Gets the language attributes for the html tag.
3141
 *
3142
 * Builds up a set of html attributes containing the text direction and language
3143
 * information for the page.
3144
 *
3145
 * @since 4.3.0
3146
 *
3147
 * @param string $doctype Optional. The type of html document. Accepts 'xhtml' or 'html'. Default 'html'.
3148
 */
3149
function get_language_attributes( $doctype = 'html' ) {
3150
	$attributes = array();
3151
3152
	if ( function_exists( 'is_rtl' ) && is_rtl() )
3153
		$attributes[] = 'dir="rtl"';
3154
3155
	if ( $lang = get_bloginfo('language') ) {
3156
		if ( get_option('html_type') == 'text/html' || $doctype == 'html' )
3157
			$attributes[] = "lang=\"$lang\"";
3158
3159
		if ( get_option('html_type') != 'text/html' || $doctype == 'xhtml' )
3160
			$attributes[] = "xml:lang=\"$lang\"";
3161
	}
3162
3163
	$output = implode(' ', $attributes);
3164
3165
	/**
3166
	 * Filters the language attributes for display in the html tag.
3167
	 *
3168
	 * @since 2.5.0
3169
	 * @since 4.3.0 Added the `$doctype` parameter.
3170
	 *
3171
	 * @param string $output A space-separated list of language attributes.
3172
	 * @param string $doctype The type of html document (xhtml|html).
3173
	 */
3174
	return apply_filters( 'language_attributes', $output, $doctype );
3175
}
3176
3177
/**
3178
 * Displays the language attributes for the html tag.
3179
 *
3180
 * Builds up a set of html attributes containing the text direction and language
3181
 * information for the page.
3182
 *
3183
 * @since 2.1.0
3184
 * @since 4.3.0 Converted into a wrapper for get_language_attributes().
3185
 *
3186
 * @param string $doctype Optional. The type of html document. Accepts 'xhtml' or 'html'. Default 'html'.
3187
 */
3188
function language_attributes( $doctype = 'html' ) {
3189
	echo get_language_attributes( $doctype );
3190
}
3191
3192
/**
3193
 * Retrieve paginated link for archive post pages.
3194
 *
3195
 * Technically, the function can be used to create paginated link list for any
3196
 * area. The 'base' argument is used to reference the url, which will be used to
3197
 * create the paginated links. The 'format' argument is then used for replacing
3198
 * the page number. It is however, most likely and by default, to be used on the
3199
 * archive post pages.
3200
 *
3201
 * The 'type' argument controls format of the returned value. The default is
3202
 * 'plain', which is just a string with the links separated by a newline
3203
 * character. The other possible values are either 'array' or 'list'. The
3204
 * 'array' value will return an array of the paginated link list to offer full
3205
 * control of display. The 'list' value will place all of the paginated links in
3206
 * an unordered HTML list.
3207
 *
3208
 * The 'total' argument is the total amount of pages and is an integer. The
3209
 * 'current' argument is the current page number and is also an integer.
3210
 *
3211
 * An example of the 'base' argument is "http://example.com/all_posts.php%_%"
3212
 * and the '%_%' is required. The '%_%' will be replaced by the contents of in
3213
 * the 'format' argument. An example for the 'format' argument is "?page=%#%"
3214
 * and the '%#%' is also required. The '%#%' will be replaced with the page
3215
 * number.
3216
 *
3217
 * You can include the previous and next links in the list by setting the
3218
 * 'prev_next' argument to true, which it is by default. You can set the
3219
 * previous text, by using the 'prev_text' argument. You can set the next text
3220
 * by setting the 'next_text' argument.
3221
 *
3222
 * If the 'show_all' argument is set to true, then it will show all of the pages
3223
 * instead of a short list of the pages near the current page. By default, the
3224
 * 'show_all' is set to false and controlled by the 'end_size' and 'mid_size'
3225
 * arguments. The 'end_size' argument is how many numbers on either the start
3226
 * and the end list edges, by default is 1. The 'mid_size' argument is how many
3227
 * numbers to either side of current page, but not including current page.
3228
 *
3229
 * It is possible to add query vars to the link by using the 'add_args' argument
3230
 * and see add_query_arg() for more information.
3231
 *
3232
 * The 'before_page_number' and 'after_page_number' arguments allow users to
3233
 * augment the links themselves. Typically this might be to add context to the
3234
 * numbered links so that screen reader users understand what the links are for.
3235
 * The text strings are added before and after the page number - within the
3236
 * anchor tag.
3237
 *
3238
 * @since 2.1.0
3239
 *
3240
 * @global WP_Query   $wp_query
3241
 * @global WP_Rewrite $wp_rewrite
3242
 *
3243
 * @param string|array $args {
3244
 *     Optional. Array or string of arguments for generating paginated links for archives.
3245
 *
3246
 *     @type string $base               Base of the paginated url. Default empty.
3247
 *     @type string $format             Format for the pagination structure. Default empty.
3248
 *     @type int    $total              The total amount of pages. Default is the value WP_Query's
3249
 *                                      `max_num_pages` or 1.
3250
 *     @type int    $current            The current page number. Default is 'paged' query var or 1.
3251
 *     @type bool   $show_all           Whether to show all pages. Default false.
3252
 *     @type int    $end_size           How many numbers on either the start and the end list edges.
3253
 *                                      Default 1.
3254
 *     @type int    $mid_size           How many numbers to either side of the current pages. Default 2.
3255
 *     @type bool   $prev_next          Whether to include the previous and next links in the list. Default true.
3256
 *     @type bool   $prev_text          The previous page text. Default '&laquo; Previous'.
3257
 *     @type bool   $next_text          The next page text. Default 'Next &raquo;'.
3258
 *     @type string $type               Controls format of the returned value. Possible values are 'plain',
3259
 *                                      'array' and 'list'. Default is 'plain'.
3260
 *     @type array  $add_args           An array of query args to add. Default false.
3261
 *     @type string $add_fragment       A string to append to each link. Default empty.
3262
 *     @type string $before_page_number A string to appear before the page number. Default empty.
3263
 *     @type string $after_page_number  A string to append after the page number. Default empty.
3264
 * }
3265
 * @return array|string|void String of page links or array of page links.
3266
 */
3267
function paginate_links( $args = '' ) {
3268
	global $wp_query, $wp_rewrite;
3269
3270
	// Setting up default values based on the current URL.
3271
	$pagenum_link = html_entity_decode( get_pagenum_link() );
3272
	$url_parts    = explode( '?', $pagenum_link );
3273
3274
	// Get max pages and current page out of the current query, if available.
3275
	$total   = isset( $wp_query->max_num_pages ) ? $wp_query->max_num_pages : 1;
3276
	$current = get_query_var( 'paged' ) ? intval( get_query_var( 'paged' ) ) : 1;
3277
3278
	// Append the format placeholder to the base URL.
3279
	$pagenum_link = trailingslashit( $url_parts[0] ) . '%_%';
3280
3281
	// URL base depends on permalink settings.
3282
	$format  = $wp_rewrite->using_index_permalinks() && ! strpos( $pagenum_link, 'index.php' ) ? 'index.php/' : '';
3283
	$format .= $wp_rewrite->using_permalinks() ? user_trailingslashit( $wp_rewrite->pagination_base . '/%#%', 'paged' ) : '?paged=%#%';
3284
3285
	$defaults = array(
3286
		'base' => $pagenum_link, // http://example.com/all_posts.php%_% : %_% is replaced by format (below)
3287
		'format' => $format, // ?page=%#% : %#% is replaced by the page number
3288
		'total' => $total,
3289
		'current' => $current,
3290
		'show_all' => false,
3291
		'prev_next' => true,
3292
		'prev_text' => __('&laquo; Previous'),
3293
		'next_text' => __('Next &raquo;'),
3294
		'end_size' => 1,
3295
		'mid_size' => 2,
3296
		'type' => 'plain',
3297
		'add_args' => array(), // array of query args to add
3298
		'add_fragment' => '',
3299
		'before_page_number' => '',
3300
		'after_page_number' => ''
3301
	);
3302
3303
	$args = wp_parse_args( $args, $defaults );
3304
3305
	if ( ! is_array( $args['add_args'] ) ) {
3306
		$args['add_args'] = array();
3307
	}
3308
3309
	// Merge additional query vars found in the original URL into 'add_args' array.
3310
	if ( isset( $url_parts[1] ) ) {
3311
		// Find the format argument.
3312
		$format = explode( '?', str_replace( '%_%', $args['format'], $args['base'] ) );
3313
		$format_query = isset( $format[1] ) ? $format[1] : '';
3314
		wp_parse_str( $format_query, $format_args );
3315
3316
		// Find the query args of the requested URL.
3317
		wp_parse_str( $url_parts[1], $url_query_args );
3318
3319
		// Remove the format argument from the array of query arguments, to avoid overwriting custom format.
3320
		foreach ( $format_args as $format_arg => $format_arg_value ) {
3321
			unset( $url_query_args[ $format_arg ] );
3322
		}
3323
3324
		$args['add_args'] = array_merge( $args['add_args'], urlencode_deep( $url_query_args ) );
3325
	}
3326
3327
	// Who knows what else people pass in $args
3328
	$total = (int) $args['total'];
3329
	if ( $total < 2 ) {
3330
		return;
3331
	}
3332
	$current  = (int) $args['current'];
3333
	$end_size = (int) $args['end_size']; // Out of bounds?  Make it the default.
3334
	if ( $end_size < 1 ) {
3335
		$end_size = 1;
3336
	}
3337
	$mid_size = (int) $args['mid_size'];
3338
	if ( $mid_size < 0 ) {
3339
		$mid_size = 2;
3340
	}
3341
	$add_args = $args['add_args'];
3342
	$r = '';
3343
	$page_links = array();
3344
	$dots = false;
3345
3346
	if ( $args['prev_next'] && $current && 1 < $current ) :
3347
		$link = str_replace( '%_%', 2 == $current ? '' : $args['format'], $args['base'] );
3348
		$link = str_replace( '%#%', $current - 1, $link );
3349
		if ( $add_args )
0 ignored issues
show
Bug Best Practice introduced by
The expression $add_args of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
3350
			$link = add_query_arg( $add_args, $link );
3351
		$link .= $args['add_fragment'];
3352
3353
		/**
3354
		 * Filters the paginated links for the given archive pages.
3355
		 *
3356
		 * @since 3.0.0
3357
		 *
3358
		 * @param string $link The paginated link URL.
3359
		 */
3360
		$page_links[] = '<a class="prev page-numbers" href="' . esc_url( apply_filters( 'paginate_links', $link ) ) . '">' . $args['prev_text'] . '</a>';
3361
	endif;
3362
	for ( $n = 1; $n <= $total; $n++ ) :
3363
		if ( $n == $current ) :
3364
			$page_links[] = "<span class='page-numbers current'>" . $args['before_page_number'] . number_format_i18n( $n ) . $args['after_page_number'] . "</span>";
3365
			$dots = true;
3366
		else :
3367
			if ( $args['show_all'] || ( $n <= $end_size || ( $current && $n >= $current - $mid_size && $n <= $current + $mid_size ) || $n > $total - $end_size ) ) :
3368
				$link = str_replace( '%_%', 1 == $n ? '' : $args['format'], $args['base'] );
3369
				$link = str_replace( '%#%', $n, $link );
3370
				if ( $add_args )
0 ignored issues
show
Bug Best Practice introduced by
The expression $add_args of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
3371
					$link = add_query_arg( $add_args, $link );
3372
				$link .= $args['add_fragment'];
3373
3374
				/** This filter is documented in wp-includes/general-template.php */
3375
				$page_links[] = "<a class='page-numbers' href='" . esc_url( apply_filters( 'paginate_links', $link ) ) . "'>" . $args['before_page_number'] . number_format_i18n( $n ) . $args['after_page_number'] . "</a>";
3376
				$dots = true;
3377
			elseif ( $dots && ! $args['show_all'] ) :
3378
				$page_links[] = '<span class="page-numbers dots">' . __( '&hellip;' ) . '</span>';
3379
				$dots = false;
3380
			endif;
3381
		endif;
3382
	endfor;
3383
	if ( $args['prev_next'] && $current && $current < $total ) :
3384
		$link = str_replace( '%_%', $args['format'], $args['base'] );
3385
		$link = str_replace( '%#%', $current + 1, $link );
3386
		if ( $add_args )
0 ignored issues
show
Bug Best Practice introduced by
The expression $add_args of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
3387
			$link = add_query_arg( $add_args, $link );
3388
		$link .= $args['add_fragment'];
3389
3390
		/** This filter is documented in wp-includes/general-template.php */
3391
		$page_links[] = '<a class="next page-numbers" href="' . esc_url( apply_filters( 'paginate_links', $link ) ) . '">' . $args['next_text'] . '</a>';
3392
	endif;
3393
	switch ( $args['type'] ) {
3394
		case 'array' :
3395
			return $page_links;
3396
3397
		case 'list' :
3398
			$r .= "<ul class='page-numbers'>\n\t<li>";
3399
			$r .= join("</li>\n\t<li>", $page_links);
3400
			$r .= "</li>\n</ul>\n";
3401
			break;
3402
3403
		default :
3404
			$r = join("\n", $page_links);
3405
			break;
3406
	}
3407
	return $r;
3408
}
3409
3410
/**
3411
 * Registers an admin colour scheme css file.
3412
 *
3413
 * Allows a plugin to register a new admin colour scheme. For example:
3414
 *
3415
 *     wp_admin_css_color( 'classic', __( 'Classic' ), admin_url( "css/colors-classic.css" ), array(
3416
 *         '#07273E', '#14568A', '#D54E21', '#2683AE'
3417
 *     ) );
3418
 *
3419
 * @since 2.5.0
3420
 *
3421
 * @global array $_wp_admin_css_colors
3422
 *
3423
 * @param string $key    The unique key for this theme.
3424
 * @param string $name   The name of the theme.
3425
 * @param string $url    The URL of the CSS file containing the color scheme.
3426
 * @param array  $colors Optional. An array of CSS color definition strings which are used
3427
 *                       to give the user a feel for the theme.
3428
 * @param array  $icons {
3429
 *     Optional. CSS color definitions used to color any SVG icons.
3430
 *
3431
 *     @type string $base    SVG icon base color.
3432
 *     @type string $focus   SVG icon color on focus.
3433
 *     @type string $current SVG icon color of current admin menu link.
3434
 * }
3435
 */
3436
function wp_admin_css_color( $key, $name, $url, $colors = array(), $icons = array() ) {
3437
	global $_wp_admin_css_colors;
3438
3439
	if ( !isset($_wp_admin_css_colors) )
3440
		$_wp_admin_css_colors = array();
3441
3442
	$_wp_admin_css_colors[$key] = (object) array(
3443
		'name' => $name,
3444
		'url' => $url,
3445
		'colors' => $colors,
3446
		'icon_colors' => $icons,
3447
	);
3448
}
3449
3450
/**
3451
 * Registers the default Admin color schemes
3452
 *
3453
 * @since 3.0.0
3454
 */
3455
function register_admin_color_schemes() {
3456
	$suffix = is_rtl() ? '-rtl' : '';
3457
	$suffix .= SCRIPT_DEBUG ? '' : '.min';
3458
3459
	wp_admin_css_color( 'fresh', _x( 'Default', 'admin color scheme' ),
3460
		false,
3461
		array( '#222', '#333', '#0073aa', '#00a0d2' ),
3462
		array( 'base' => '#82878c', 'focus' => '#00a0d2', 'current' => '#fff' )
3463
	);
3464
3465
	// Other color schemes are not available when running out of src
3466
	if ( false !== strpos( get_bloginfo( 'version' ), '-src' ) ) {
3467
		return;
3468
	}
3469
3470
	wp_admin_css_color( 'light', _x( 'Light', 'admin color scheme' ),
3471
		admin_url( "css/colors/light/colors$suffix.css" ),
3472
		array( '#e5e5e5', '#999', '#d64e07', '#04a4cc' ),
3473
		array( 'base' => '#999', 'focus' => '#ccc', 'current' => '#ccc' )
3474
	);
3475
3476
	wp_admin_css_color( 'blue', _x( 'Blue', 'admin color scheme' ),
3477
		admin_url( "css/colors/blue/colors$suffix.css" ),
3478
		array( '#096484', '#4796b3', '#52accc', '#74B6CE' ),
3479
		array( 'base' => '#e5f8ff', 'focus' => '#fff', 'current' => '#fff' )
3480
	);
3481
3482
	wp_admin_css_color( 'midnight', _x( 'Midnight', 'admin color scheme' ),
3483
		admin_url( "css/colors/midnight/colors$suffix.css" ),
3484
		array( '#25282b', '#363b3f', '#69a8bb', '#e14d43' ),
3485
		array( 'base' => '#f1f2f3', 'focus' => '#fff', 'current' => '#fff' )
3486
	);
3487
3488
	wp_admin_css_color( 'sunrise', _x( 'Sunrise', 'admin color scheme' ),
3489
		admin_url( "css/colors/sunrise/colors$suffix.css" ),
3490
		array( '#b43c38', '#cf4944', '#dd823b', '#ccaf0b' ),
3491
		array( 'base' => '#f3f1f1', 'focus' => '#fff', 'current' => '#fff' )
3492
	);
3493
3494
	wp_admin_css_color( 'ectoplasm', _x( 'Ectoplasm', 'admin color scheme' ),
3495
		admin_url( "css/colors/ectoplasm/colors$suffix.css" ),
3496
		array( '#413256', '#523f6d', '#a3b745', '#d46f15' ),
3497
		array( 'base' => '#ece6f6', 'focus' => '#fff', 'current' => '#fff' )
3498
	);
3499
3500
	wp_admin_css_color( 'ocean', _x( 'Ocean', 'admin color scheme' ),
3501
		admin_url( "css/colors/ocean/colors$suffix.css" ),
3502
		array( '#627c83', '#738e96', '#9ebaa0', '#aa9d88' ),
3503
		array( 'base' => '#f2fcff', 'focus' => '#fff', 'current' => '#fff' )
3504
	);
3505
3506
	wp_admin_css_color( 'coffee', _x( 'Coffee', 'admin color scheme' ),
3507
		admin_url( "css/colors/coffee/colors$suffix.css" ),
3508
		array( '#46403c', '#59524c', '#c7a589', '#9ea476' ),
3509
		array( 'base' => '#f3f2f1', 'focus' => '#fff', 'current' => '#fff' )
3510
	);
3511
3512
}
3513
3514
/**
3515
 * Displays the URL of a WordPress admin CSS file.
3516
 *
3517
 * @see WP_Styles::_css_href and its {@see 'style_loader_src'} filter.
3518
 *
3519
 * @since 2.3.0
3520
 *
3521
 * @param string $file file relative to wp-admin/ without its ".css" extension.
3522
 * @return string
3523
 */
3524
function wp_admin_css_uri( $file = 'wp-admin' ) {
3525
	if ( defined('WP_INSTALLING') ) {
3526
		$_file = "./$file.css";
3527
	} else {
3528
		$_file = admin_url("$file.css");
3529
	}
3530
	$_file = add_query_arg( 'version', get_bloginfo( 'version' ),  $_file );
3531
3532
	/**
3533
	 * Filters the URI of a WordPress admin CSS file.
3534
	 *
3535
	 * @since 2.3.0
3536
	 *
3537
	 * @param string $_file Relative path to the file with query arguments attached.
3538
	 * @param string $file  Relative path to the file, minus its ".css" extension.
3539
	 */
3540
	return apply_filters( 'wp_admin_css_uri', $_file, $file );
3541
}
3542
3543
/**
3544
 * Enqueues or directly prints a stylesheet link to the specified CSS file.
3545
 *
3546
 * "Intelligently" decides to enqueue or to print the CSS file. If the
3547
 * {@see 'wp_print_styles'} action has *not* yet been called, the CSS file will be
3548
 * enqueued. If the {@see 'wp_print_styles'} action has been called, the CSS link will
3549
 * be printed. Printing may be forced by passing true as the $force_echo
3550
 * (second) parameter.
3551
 *
3552
 * For backward compatibility with WordPress 2.3 calling method: If the $file
3553
 * (first) parameter does not correspond to a registered CSS file, we assume
3554
 * $file is a file relative to wp-admin/ without its ".css" extension. A
3555
 * stylesheet link to that generated URL is printed.
3556
 *
3557
 * @since 2.3.0
3558
 *
3559
 * @param string $file       Optional. Style handle name or file name (without ".css" extension) relative
3560
 * 	                         to wp-admin/. Defaults to 'wp-admin'.
3561
 * @param bool   $force_echo Optional. Force the stylesheet link to be printed rather than enqueued.
3562
 */
3563
function wp_admin_css( $file = 'wp-admin', $force_echo = false ) {
3564
	// For backward compatibility
3565
	$handle = 0 === strpos( $file, 'css/' ) ? substr( $file, 4 ) : $file;
3566
3567
	if ( wp_styles()->query( $handle ) ) {
3568
		if ( $force_echo || did_action( 'wp_print_styles' ) ) // we already printed the style queue. Print this one immediately
3569
			wp_print_styles( $handle );
3570
		else // Add to style queue
3571
			wp_enqueue_style( $handle );
3572
		return;
3573
	}
3574
3575
	/**
3576
	 * Filters the stylesheet link to the specified CSS file.
3577
	 *
3578
	 * If the site is set to display right-to-left, the RTL stylesheet link
3579
	 * will be used instead.
3580
	 *
3581
	 * @since 2.3.0
3582
	 * @param string $stylesheet_link HTML link element for the stylesheet.
3583
	 * @param string $file            Style handle name or filename (without ".css" extension)
3584
	 *                                relative to wp-admin/. Defaults to 'wp-admin'.
3585
	 */
3586
	echo apply_filters( 'wp_admin_css', "<link rel='stylesheet' href='" . esc_url( wp_admin_css_uri( $file ) ) . "' type='text/css' />\n", $file );
3587
3588
	if ( function_exists( 'is_rtl' ) && is_rtl() ) {
3589
		/** This filter is documented in wp-includes/general-template.php */
3590
		echo apply_filters( 'wp_admin_css', "<link rel='stylesheet' href='" . esc_url( wp_admin_css_uri( "$file-rtl" ) ) . "' type='text/css' />\n", "$file-rtl" );
3591
	}
3592
}
3593
3594
/**
3595
 * Enqueues the default ThickBox js and css.
3596
 *
3597
 * If any of the settings need to be changed, this can be done with another js
3598
 * file similar to media-upload.js. That file should
3599
 * require array('thickbox') to ensure it is loaded after.
3600
 *
3601
 * @since 2.5.0
3602
 */
3603
function add_thickbox() {
3604
	wp_enqueue_script( 'thickbox' );
3605
	wp_enqueue_style( 'thickbox' );
3606
3607
	if ( is_network_admin() )
3608
		add_action( 'admin_head', '_thickbox_path_admin_subfolder' );
3609
}
3610
3611
/**
3612
 * Displays the XHTML generator that is generated on the wp_head hook.
3613
 *
3614
 * See {@see 'wp_head'}.
3615
 *
3616
 * @since 2.5.0
3617
 */
3618
function wp_generator() {
3619
	/**
3620
	 * Filters the output of the XHTML generator tag.
3621
	 *
3622
	 * @since 2.5.0
3623
	 *
3624
	 * @param string $generator_type The XHTML generator.
3625
	 */
3626
	the_generator( apply_filters( 'wp_generator_type', 'xhtml' ) );
3627
}
3628
3629
/**
3630
 * Display the generator XML or Comment for RSS, ATOM, etc.
3631
 *
3632
 * Returns the correct generator type for the requested output format. Allows
3633
 * for a plugin to filter generators overall the {@see 'the_generator'} filter.
3634
 *
3635
 * @since 2.5.0
3636
 *
3637
 * @param string $type The type of generator to output - (html|xhtml|atom|rss2|rdf|comment|export).
3638
 */
3639
function the_generator( $type ) {
3640
	/**
3641
	 * Filters the output of the XHTML generator tag for display.
3642
	 *
3643
	 * @since 2.5.0
3644
	 *
3645
	 * @param string $generator_type The generator output.
3646
	 * @param string $type           The type of generator to output. Accepts 'html',
3647
	 *                               'xhtml', 'atom', 'rss2', 'rdf', 'comment', 'export'.
3648
	 */
3649
	echo apply_filters( 'the_generator', get_the_generator($type), $type ) . "\n";
3650
}
3651
3652
/**
3653
 * Creates the generator XML or Comment for RSS, ATOM, etc.
3654
 *
3655
 * Returns the correct generator type for the requested output format. Allows
3656
 * for a plugin to filter generators on an individual basis using the
3657
 * {@see 'get_the_generator_$type'} filter.
3658
 *
3659
 * @since 2.5.0
3660
 *
3661
 * @param string $type The type of generator to return - (html|xhtml|atom|rss2|rdf|comment|export).
3662
 * @return string|void The HTML content for the generator.
3663
 */
3664
function get_the_generator( $type = '' ) {
3665
	if ( empty( $type ) ) {
3666
3667
		$current_filter = current_filter();
3668
		if ( empty( $current_filter ) )
3669
			return;
3670
3671
		switch ( $current_filter ) {
3672
			case 'rss2_head' :
3673
			case 'commentsrss2_head' :
3674
				$type = 'rss2';
3675
				break;
3676
			case 'rss_head' :
3677
			case 'opml_head' :
3678
				$type = 'comment';
3679
				break;
3680
			case 'rdf_header' :
3681
				$type = 'rdf';
3682
				break;
3683
			case 'atom_head' :
3684
			case 'comments_atom_head' :
3685
			case 'app_head' :
3686
				$type = 'atom';
3687
				break;
3688
		}
3689
	}
3690
3691
	switch ( $type ) {
3692
		case 'html':
3693
			$gen = '<meta name="generator" content="WordPress ' . get_bloginfo( 'version' ) . '">';
3694
			break;
3695
		case 'xhtml':
3696
			$gen = '<meta name="generator" content="WordPress ' . get_bloginfo( 'version' ) . '" />';
3697
			break;
3698
		case 'atom':
3699
			$gen = '<generator uri="https://wordpress.org/" version="' . get_bloginfo_rss( 'version' ) . '">WordPress</generator>';
3700
			break;
3701
		case 'rss2':
3702
			$gen = '<generator>https://wordpress.org/?v=' . get_bloginfo_rss( 'version' ) . '</generator>';
3703
			break;
3704
		case 'rdf':
3705
			$gen = '<admin:generatorAgent rdf:resource="https://wordpress.org/?v=' . get_bloginfo_rss( 'version' ) . '" />';
3706
			break;
3707
		case 'comment':
3708
			$gen = '<!-- generator="WordPress/' . get_bloginfo( 'version' ) . '" -->';
3709
			break;
3710
		case 'export':
3711
			$gen = '<!-- generator="WordPress/' . get_bloginfo_rss('version') . '" created="'. date('Y-m-d H:i') . '" -->';
3712
			break;
3713
	}
3714
3715
	/**
3716
	 * Filters the HTML for the retrieved generator type.
3717
	 *
3718
	 * The dynamic portion of the hook name, `$type`, refers to the generator type.
3719
	 *
3720
	 * @since 2.5.0
3721
	 *
3722
	 * @param string $gen  The HTML markup output to wp_head().
3723
	 * @param string $type The type of generator. Accepts 'html', 'xhtml', 'atom',
3724
	 *                     'rss2', 'rdf', 'comment', 'export'.
3725
	 */
3726
	return apply_filters( "get_the_generator_{$type}", $gen, $type );
0 ignored issues
show
The variable $gen does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
3727
}
3728
3729
/**
3730
 * Outputs the html checked attribute.
3731
 *
3732
 * Compares the first two arguments and if identical marks as checked
3733
 *
3734
 * @since 1.0.0
3735
 *
3736
 * @param mixed $checked One of the values to compare
3737
 * @param mixed $current (true) The other value to compare if not just true
3738
 * @param bool  $echo    Whether to echo or just return the string
3739
 * @return string html attribute or empty string
3740
 */
3741
function checked( $checked, $current = true, $echo = true ) {
3742
	return __checked_selected_helper( $checked, $current, $echo, 'checked' );
3743
}
3744
3745
/**
3746
 * Outputs the html selected attribute.
3747
 *
3748
 * Compares the first two arguments and if identical marks as selected
3749
 *
3750
 * @since 1.0.0
3751
 *
3752
 * @param mixed $selected One of the values to compare
3753
 * @param mixed $current  (true) The other value to compare if not just true
3754
 * @param bool  $echo     Whether to echo or just return the string
3755
 * @return string html attribute or empty string
3756
 */
3757
function selected( $selected, $current = true, $echo = true ) {
3758
	return __checked_selected_helper( $selected, $current, $echo, 'selected' );
3759
}
3760
3761
/**
3762
 * Outputs the html disabled attribute.
3763
 *
3764
 * Compares the first two arguments and if identical marks as disabled
3765
 *
3766
 * @since 3.0.0
3767
 *
3768
 * @param mixed $disabled One of the values to compare
3769
 * @param mixed $current  (true) The other value to compare if not just true
3770
 * @param bool  $echo     Whether to echo or just return the string
3771
 * @return string html attribute or empty string
3772
 */
3773
function disabled( $disabled, $current = true, $echo = true ) {
3774
	return __checked_selected_helper( $disabled, $current, $echo, 'disabled' );
3775
}
3776
3777
/**
3778
 * Private helper function for checked, selected, and disabled.
3779
 *
3780
 * Compares the first two arguments and if identical marks as $type
3781
 *
3782
 * @since 2.8.0
3783
 * @access private
3784
 *
3785
 * @param mixed  $helper  One of the values to compare
3786
 * @param mixed  $current (true) The other value to compare if not just true
3787
 * @param bool   $echo    Whether to echo or just return the string
3788
 * @param string $type    The type of checked|selected|disabled we are doing
3789
 * @return string html attribute or empty string
3790
 */
3791
function __checked_selected_helper( $helper, $current, $echo, $type ) {
3792
	if ( (string) $helper === (string) $current )
3793
		$result = " $type='$type'";
3794
	else
3795
		$result = '';
3796
3797
	if ( $echo )
3798
		echo $result;
3799
3800
	return $result;
3801
}
3802
3803
/**
3804
 * Default settings for heartbeat
3805
 *
3806
 * Outputs the nonce used in the heartbeat XHR
3807
 *
3808
 * @since 3.6.0
3809
 *
3810
 * @param array $settings
3811
 * @return array $settings
3812
 */
3813
function wp_heartbeat_settings( $settings ) {
3814
	if ( ! is_admin() )
3815
		$settings['ajaxurl'] = admin_url( 'admin-ajax.php', 'relative' );
3816
3817
	if ( is_user_logged_in() )
3818
		$settings['nonce'] = wp_create_nonce( 'heartbeat-nonce' );
3819
3820
	return $settings;
3821
}
3822