1 | <?php |
---|
2 | /** |
---|
3 | * These functions can be replaced via plugins. If plugins do not redefine these |
---|
4 | * functions, then these will be used instead. |
---|
5 | * |
---|
6 | * @package WordPress |
---|
7 | */ |
---|
8 | |
---|
9 | if ( !function_exists('wp_set_current_user') ) : |
---|
10 | /** |
---|
11 | * Changes the current user by ID or name. |
---|
12 | * |
---|
13 | * Set $id to null and specify a name if you do not know a user's ID. |
---|
14 | * |
---|
15 | * Some WordPress functionality is based on the current user and not based on |
---|
16 | * the signed in user. Therefore, it opens the ability to edit and perform |
---|
17 | * actions on users who aren't signed in. |
---|
18 | * |
---|
19 | * @since 2.0.3 |
---|
20 | * @global object $current_user The current user object which holds the user data. |
---|
21 | * |
---|
22 | * @param int $id User ID |
---|
23 | * @param string $name User's username |
---|
24 | * @return WP_User Current user User object |
---|
25 | */ |
---|
26 | function wp_set_current_user($id, $name = '') { |
---|
27 | global $current_user; |
---|
28 | |
---|
29 | if ( isset( $current_user ) && ( $current_user instanceof WP_User ) && ( $id == $current_user->ID ) ) |
---|
30 | return $current_user; |
---|
31 | |
---|
32 | $current_user = new WP_User( $id, $name ); |
---|
33 | |
---|
34 | setup_userdata( $current_user->ID ); |
---|
35 | |
---|
36 | /** |
---|
37 | * Fires after the current user is set. |
---|
38 | * |
---|
39 | * @since 2.0.1 |
---|
40 | */ |
---|
41 | do_action( 'set_current_user' ); |
---|
42 | |
---|
43 | return $current_user; |
---|
44 | } |
---|
45 | endif; |
---|
46 | |
---|
47 | if ( !function_exists('wp_get_current_user') ) : |
---|
48 | /** |
---|
49 | * Retrieve the current user object. |
---|
50 | * |
---|
51 | * @since 2.0.3 |
---|
52 | * |
---|
53 | * @return WP_User Current user WP_User object |
---|
54 | */ |
---|
55 | function wp_get_current_user() { |
---|
56 | global $current_user; |
---|
57 | |
---|
58 | get_currentuserinfo(); |
---|
59 | |
---|
60 | return $current_user; |
---|
61 | } |
---|
62 | endif; |
---|
63 | |
---|
64 | if ( !function_exists('get_currentuserinfo') ) : |
---|
65 | /** |
---|
66 | * Populate global variables with information about the currently logged in user. |
---|
67 | * |
---|
68 | * Will set the current user, if the current user is not set. The current user |
---|
69 | * will be set to the logged-in person. If no user is logged-in, then it will |
---|
70 | * set the current user to 0, which is invalid and won't have any permissions. |
---|
71 | * |
---|
72 | * @since 0.71 |
---|
73 | * |
---|
74 | * @uses $current_user Checks if the current user is set |
---|
75 | * @uses wp_validate_auth_cookie() Retrieves current logged in user. |
---|
76 | * |
---|
77 | * @return bool|null False on XML-RPC Request and invalid auth cookie. Null when current user set. |
---|
78 | */ |
---|
79 | function get_currentuserinfo() { |
---|
80 | global $current_user; |
---|
81 | |
---|
82 | if ( ! empty( $current_user ) ) { |
---|
83 | if ( $current_user instanceof WP_User ) |
---|
84 | return; |
---|
85 | |
---|
86 | // Upgrade stdClass to WP_User |
---|
87 | if ( is_object( $current_user ) && isset( $current_user->ID ) ) { |
---|
88 | $cur_id = $current_user->ID; |
---|
89 | $current_user = null; |
---|
90 | wp_set_current_user( $cur_id ); |
---|
91 | return; |
---|
92 | } |
---|
93 | |
---|
94 | // $current_user has a junk value. Force to WP_User with ID 0. |
---|
95 | $current_user = null; |
---|
96 | wp_set_current_user( 0 ); |
---|
97 | return false; |
---|
98 | } |
---|
99 | |
---|
100 | if ( defined('XMLRPC_REQUEST') && XMLRPC_REQUEST ) { |
---|
101 | wp_set_current_user( 0 ); |
---|
102 | return false; |
---|
103 | } |
---|
104 | |
---|
105 | /** |
---|
106 | * Filter the current user. |
---|
107 | * |
---|
108 | * The default filters use this to determine the current user from the |
---|
109 | * request's cookies, if available. |
---|
110 | * |
---|
111 | * Returning a value of false will effectively short-circuit setting |
---|
112 | * the current user. |
---|
113 | * |
---|
114 | * @since 3.9.0 |
---|
115 | * |
---|
116 | * @param int|bool $user_id User ID if one has been determined, false otherwise. |
---|
117 | */ |
---|
118 | $user_id = apply_filters( 'determine_current_user', false ); |
---|
119 | if ( ! $user_id ) { |
---|
120 | wp_set_current_user( 0 ); |
---|
121 | return false; |
---|
122 | } |
---|
123 | |
---|
124 | wp_set_current_user( $user_id ); |
---|
125 | } |
---|
126 | endif; |
---|
127 | |
---|
128 | if ( !function_exists('get_userdata') ) : |
---|
129 | /** |
---|
130 | * Retrieve user info by user ID. |
---|
131 | * |
---|
132 | * @since 0.71 |
---|
133 | * |
---|
134 | * @param int $user_id User ID |
---|
135 | * @return WP_User|bool WP_User object on success, false on failure. |
---|
136 | */ |
---|
137 | function get_userdata( $user_id ) { |
---|
138 | return get_user_by( 'id', $user_id ); |
---|
139 | } |
---|
140 | endif; |
---|
141 | |
---|
142 | if ( !function_exists('get_user_by') ) : |
---|
143 | /** |
---|
144 | * Retrieve user info by a given field |
---|
145 | * |
---|
146 | * @since 2.8.0 |
---|
147 | * |
---|
148 | * @param string $field The field to retrieve the user with. id | slug | email | login |
---|
149 | * @param int|string $value A value for $field. A user ID, slug, email address, or login name. |
---|
150 | * @return WP_User|bool WP_User object on success, false on failure. |
---|
151 | */ |
---|
152 | function get_user_by( $field, $value ) { |
---|
153 | $userdata = WP_User::get_data_by( $field, $value ); |
---|
154 | |
---|
155 | if ( !$userdata ) |
---|
156 | return false; |
---|
157 | |
---|
158 | $user = new WP_User; |
---|
159 | $user->init( $userdata ); |
---|
160 | |
---|
161 | return $user; |
---|
162 | } |
---|
163 | endif; |
---|
164 | |
---|
165 | if ( !function_exists('cache_users') ) : |
---|
166 | /** |
---|
167 | * Retrieve info for user lists to prevent multiple queries by get_userdata() |
---|
168 | * |
---|
169 | * @since 3.0.0 |
---|
170 | * |
---|
171 | * @param array $user_ids User ID numbers list |
---|
172 | */ |
---|
173 | function cache_users( $user_ids ) { |
---|
174 | global $wpdb; |
---|
175 | |
---|
176 | $clean = _get_non_cached_ids( $user_ids, 'users' ); |
---|
177 | |
---|
178 | if ( empty( $clean ) ) |
---|
179 | return; |
---|
180 | |
---|
181 | $list = implode( ',', $clean ); |
---|
182 | |
---|
183 | $users = $wpdb->get_results( "SELECT * FROM $wpdb->users WHERE ID IN ($list)" ); |
---|
184 | |
---|
185 | $ids = array(); |
---|
186 | foreach ( $users as $user ) { |
---|
187 | update_user_caches( $user ); |
---|
188 | $ids[] = $user->ID; |
---|
189 | } |
---|
190 | update_meta_cache( 'user', $ids ); |
---|
191 | } |
---|
192 | endif; |
---|
193 | |
---|
194 | if ( !function_exists( 'wp_mail' ) ) : |
---|
195 | /** |
---|
196 | * Send mail, similar to PHP's mail |
---|
197 | * |
---|
198 | * A true return value does not automatically mean that the user received the |
---|
199 | * email successfully. It just only means that the method used was able to |
---|
200 | * process the request without any errors. |
---|
201 | * |
---|
202 | * Using the two 'wp_mail_from' and 'wp_mail_from_name' hooks allow from |
---|
203 | * creating a from address like 'Name <email@address.com>' when both are set. If |
---|
204 | * just 'wp_mail_from' is set, then just the email address will be used with no |
---|
205 | * name. |
---|
206 | * |
---|
207 | * The default content type is 'text/plain' which does not allow using HTML. |
---|
208 | * However, you can set the content type of the email by using the |
---|
209 | * 'wp_mail_content_type' filter. |
---|
210 | * |
---|
211 | * The default charset is based on the charset used on the blog. The charset can |
---|
212 | * be set using the 'wp_mail_charset' filter. |
---|
213 | * |
---|
214 | * @since 1.2.1 |
---|
215 | * |
---|
216 | * @uses PHPMailer |
---|
217 | * |
---|
218 | * @param string|array $to Array or comma-separated list of email addresses to send message. |
---|
219 | * @param string $subject Email subject |
---|
220 | * @param string $message Message contents |
---|
221 | * @param string|array $headers Optional. Additional headers. |
---|
222 | * @param string|array $attachments Optional. Files to attach. |
---|
223 | * @return bool Whether the email contents were sent successfully. |
---|
224 | */ |
---|
225 | function wp_mail( $to, $subject, $message, $headers = '', $attachments = array() ) { |
---|
226 | // Compact the input, apply the filters, and extract them back out |
---|
227 | |
---|
228 | /** |
---|
229 | * Filter the wp_mail() arguments. |
---|
230 | * |
---|
231 | * @since 2.2.0 |
---|
232 | * |
---|
233 | * @param array $args A compacted array of wp_mail() arguments, including the "to" email, |
---|
234 | * subject, message, headers, and attachments values. |
---|
235 | */ |
---|
236 | extract( apply_filters( 'wp_mail', compact( 'to', 'subject', 'message', 'headers', 'attachments' ) ) ); |
---|
237 | |
---|
238 | if ( !is_array($attachments) ) |
---|
239 | $attachments = explode( "\n", str_replace( "\r\n", "\n", $attachments ) ); |
---|
240 | |
---|
241 | global $phpmailer; |
---|
242 | |
---|
243 | // (Re)create it, if it's gone missing |
---|
244 | if ( !is_object( $phpmailer ) || !is_a( $phpmailer, 'PHPMailer' ) ) { |
---|
245 | require_once ABSPATH . WPINC . '/class-phpmailer.php'; |
---|
246 | require_once ABSPATH . WPINC . '/class-smtp.php'; |
---|
247 | $phpmailer = new PHPMailer( true ); |
---|
248 | } |
---|
249 | |
---|
250 | // Headers |
---|
251 | if ( empty( $headers ) ) { |
---|
252 | $headers = array(); |
---|
253 | } else { |
---|
254 | if ( !is_array( $headers ) ) { |
---|
255 | // Explode the headers out, so this function can take both |
---|
256 | // string headers and an array of headers. |
---|
257 | $tempheaders = explode( "\n", str_replace( "\r\n", "\n", $headers ) ); |
---|
258 | } else { |
---|
259 | $tempheaders = $headers; |
---|
260 | } |
---|
261 | $headers = array(); |
---|
262 | $cc = array(); |
---|
263 | $bcc = array(); |
---|
264 | |
---|
265 | // If it's actually got contents |
---|
266 | if ( !empty( $tempheaders ) ) { |
---|
267 | // Iterate through the raw headers |
---|
268 | foreach ( (array) $tempheaders as $header ) { |
---|
269 | if ( strpos($header, ':') === false ) { |
---|
270 | if ( false !== stripos( $header, 'boundary=' ) ) { |
---|
271 | $parts = preg_split('/boundary=/i', trim( $header ) ); |
---|
272 | $boundary = trim( str_replace( array( "'", '"' ), '', $parts[1] ) ); |
---|
273 | } |
---|
274 | continue; |
---|
275 | } |
---|
276 | // Explode them out |
---|
277 | list( $name, $content ) = explode( ':', trim( $header ), 2 ); |
---|
278 | |
---|
279 | // Cleanup crew |
---|
280 | $name = trim( $name ); |
---|
281 | $content = trim( $content ); |
---|
282 | |
---|
283 | switch ( strtolower( $name ) ) { |
---|
284 | // Mainly for legacy -- process a From: header if it's there |
---|
285 | case 'from': |
---|
286 | if ( strpos($content, '<' ) !== false ) { |
---|
287 | // So... making my life hard again? |
---|
288 | $from_name = substr( $content, 0, strpos( $content, '<' ) - 1 ); |
---|
289 | $from_name = str_replace( '"', '', $from_name ); |
---|
290 | $from_name = trim( $from_name ); |
---|
291 | |
---|
292 | $from_email = substr( $content, strpos( $content, '<' ) + 1 ); |
---|
293 | $from_email = str_replace( '>', '', $from_email ); |
---|
294 | $from_email = trim( $from_email ); |
---|
295 | } else { |
---|
296 | $from_email = trim( $content ); |
---|
297 | } |
---|
298 | break; |
---|
299 | case 'content-type': |
---|
300 | if ( strpos( $content, ';' ) !== false ) { |
---|
301 | list( $type, $charset ) = explode( ';', $content ); |
---|
302 | $content_type = trim( $type ); |
---|
303 | if ( false !== stripos( $charset, 'charset=' ) ) { |
---|
304 | $charset = trim( str_replace( array( 'charset=', '"' ), '', $charset ) ); |
---|
305 | } elseif ( false !== stripos( $charset, 'boundary=' ) ) { |
---|
306 | $boundary = trim( str_replace( array( 'BOUNDARY=', 'boundary=', '"' ), '', $charset ) ); |
---|
307 | $charset = ''; |
---|
308 | } |
---|
309 | } else { |
---|
310 | $content_type = trim( $content ); |
---|
311 | } |
---|
312 | break; |
---|
313 | case 'cc': |
---|
314 | $cc = array_merge( (array) $cc, explode( ',', $content ) ); |
---|
315 | break; |
---|
316 | case 'bcc': |
---|
317 | $bcc = array_merge( (array) $bcc, explode( ',', $content ) ); |
---|
318 | break; |
---|
319 | default: |
---|
320 | // Add it to our grand headers array |
---|
321 | $headers[trim( $name )] = trim( $content ); |
---|
322 | break; |
---|
323 | } |
---|
324 | } |
---|
325 | } |
---|
326 | } |
---|
327 | |
---|
328 | // Empty out the values that may be set |
---|
329 | $phpmailer->ClearAllRecipients(); |
---|
330 | $phpmailer->ClearAttachments(); |
---|
331 | $phpmailer->ClearCustomHeaders(); |
---|
332 | $phpmailer->ClearReplyTos(); |
---|
333 | |
---|
334 | // From email and name |
---|
335 | // If we don't have a name from the input headers |
---|
336 | if ( !isset( $from_name ) ) |
---|
337 | $from_name = 'WordPress'; |
---|
338 | |
---|
339 | /* If we don't have an email from the input headers default to wordpress@$sitename |
---|
340 | * Some hosts will block outgoing mail from this address if it doesn't exist but |
---|
341 | * there's no easy alternative. Defaulting to admin_email might appear to be another |
---|
342 | * option but some hosts may refuse to relay mail from an unknown domain. See |
---|
343 | * http://trac.wordpress.org/ticket/5007. |
---|
344 | */ |
---|
345 | |
---|
346 | if ( !isset( $from_email ) ) { |
---|
347 | // Get the site domain and get rid of www. |
---|
348 | $sitename = strtolower( $_SERVER['SERVER_NAME'] ); |
---|
349 | if ( substr( $sitename, 0, 4 ) == 'www.' ) { |
---|
350 | $sitename = substr( $sitename, 4 ); |
---|
351 | } |
---|
352 | |
---|
353 | $from_email = 'wordpress@' . $sitename; |
---|
354 | } |
---|
355 | |
---|
356 | /** |
---|
357 | * Filter the email address to send from. |
---|
358 | * |
---|
359 | * @since 2.2.0 |
---|
360 | * |
---|
361 | * @param string $from_email Email address to send from. |
---|
362 | */ |
---|
363 | $phpmailer->From = apply_filters( 'wp_mail_from', $from_email ); |
---|
364 | |
---|
365 | /** |
---|
366 | * Filter the name to associate with the "from" email address. |
---|
367 | * |
---|
368 | * @since 2.3.0 |
---|
369 | * |
---|
370 | * @param string $from_name Name associated with the "from" email address. |
---|
371 | */ |
---|
372 | $phpmailer->FromName = apply_filters( 'wp_mail_from_name', $from_name ); |
---|
373 | |
---|
374 | // Set destination addresses |
---|
375 | if ( !is_array( $to ) ) |
---|
376 | $to = explode( ',', $to ); |
---|
377 | |
---|
378 | foreach ( (array) $to as $recipient ) { |
---|
379 | try { |
---|
380 | // Break $recipient into name and address parts if in the format "Foo <bar@baz.com>" |
---|
381 | $recipient_name = ''; |
---|
382 | if( preg_match( '/(.*)<(.+)>/', $recipient, $matches ) ) { |
---|
383 | if ( count( $matches ) == 3 ) { |
---|
384 | $recipient_name = $matches[1]; |
---|
385 | $recipient = $matches[2]; |
---|
386 | } |
---|
387 | } |
---|
388 | $phpmailer->AddAddress( $recipient, $recipient_name); |
---|
389 | } catch ( phpmailerException $e ) { |
---|
390 | continue; |
---|
391 | } |
---|
392 | } |
---|
393 | |
---|
394 | // Set mail's subject and body |
---|
395 | $phpmailer->Subject = $subject; |
---|
396 | $phpmailer->Body = $message; |
---|
397 | |
---|
398 | // Add any CC and BCC recipients |
---|
399 | if ( !empty( $cc ) ) { |
---|
400 | foreach ( (array) $cc as $recipient ) { |
---|
401 | try { |
---|
402 | // Break $recipient into name and address parts if in the format "Foo <bar@baz.com>" |
---|
403 | $recipient_name = ''; |
---|
404 | if( preg_match( '/(.*)<(.+)>/', $recipient, $matches ) ) { |
---|
405 | if ( count( $matches ) == 3 ) { |
---|
406 | $recipient_name = $matches[1]; |
---|
407 | $recipient = $matches[2]; |
---|
408 | } |
---|
409 | } |
---|
410 | $phpmailer->AddCc( $recipient, $recipient_name ); |
---|
411 | } catch ( phpmailerException $e ) { |
---|
412 | continue; |
---|
413 | } |
---|
414 | } |
---|
415 | } |
---|
416 | |
---|
417 | if ( !empty( $bcc ) ) { |
---|
418 | foreach ( (array) $bcc as $recipient) { |
---|
419 | try { |
---|
420 | // Break $recipient into name and address parts if in the format "Foo <bar@baz.com>" |
---|
421 | $recipient_name = ''; |
---|
422 | if( preg_match( '/(.*)<(.+)>/', $recipient, $matches ) ) { |
---|
423 | if ( count( $matches ) == 3 ) { |
---|
424 | $recipient_name = $matches[1]; |
---|
425 | $recipient = $matches[2]; |
---|
426 | } |
---|
427 | } |
---|
428 | $phpmailer->AddBcc( $recipient, $recipient_name ); |
---|
429 | } catch ( phpmailerException $e ) { |
---|
430 | continue; |
---|
431 | } |
---|
432 | } |
---|
433 | } |
---|
434 | |
---|
435 | // Set to use PHP's mail() |
---|
436 | $phpmailer->IsMail(); |
---|
437 | |
---|
438 | // Set Content-Type and charset |
---|
439 | // If we don't have a content-type from the input headers |
---|
440 | if ( !isset( $content_type ) ) |
---|
441 | $content_type = 'text/plain'; |
---|
442 | |
---|
443 | /** |
---|
444 | * Filter the wp_mail() content type. |
---|
445 | * |
---|
446 | * @since 2.3.0 |
---|
447 | * |
---|
448 | * @param string $content_type Default wp_mail() content type. |
---|
449 | */ |
---|
450 | $content_type = apply_filters( 'wp_mail_content_type', $content_type ); |
---|
451 | |
---|
452 | $phpmailer->ContentType = $content_type; |
---|
453 | |
---|
454 | // Set whether it's plaintext, depending on $content_type |
---|
455 | if ( 'text/html' == $content_type ) |
---|
456 | $phpmailer->IsHTML( true ); |
---|
457 | |
---|
458 | // If we don't have a charset from the input headers |
---|
459 | if ( !isset( $charset ) ) |
---|
460 | $charset = get_bloginfo( 'charset' ); |
---|
461 | |
---|
462 | // Set the content-type and charset |
---|
463 | |
---|
464 | /** |
---|
465 | * Filter the default wp_mail() charset. |
---|
466 | * |
---|
467 | * @since 2.3.0 |
---|
468 | * |
---|
469 | * @param string $charset Default email charset. |
---|
470 | */ |
---|
471 | $phpmailer->CharSet = apply_filters( 'wp_mail_charset', $charset ); |
---|
472 | |
---|
473 | // Set custom headers |
---|
474 | if ( !empty( $headers ) ) { |
---|
475 | foreach( (array) $headers as $name => $content ) { |
---|
476 | $phpmailer->AddCustomHeader( sprintf( '%1$s: %2$s', $name, $content ) ); |
---|
477 | } |
---|
478 | |
---|
479 | if ( false !== stripos( $content_type, 'multipart' ) && ! empty($boundary) ) |
---|
480 | $phpmailer->AddCustomHeader( sprintf( "Content-Type: %s;\n\t boundary=\"%s\"", $content_type, $boundary ) ); |
---|
481 | } |
---|
482 | |
---|
483 | if ( !empty( $attachments ) ) { |
---|
484 | foreach ( $attachments as $attachment ) { |
---|
485 | try { |
---|
486 | if(is_array($attachment)){ |
---|
487 | $phpmailer->AddAttachment($attachment['archive'], $attachment['name']); |
---|
488 | }else{ |
---|
489 | $phpmailer->AddAttachment($attachment); |
---|
490 | } |
---|
491 | } catch ( phpmailerException $e ) { |
---|
492 | continue; |
---|
493 | } |
---|
494 | } |
---|
495 | } |
---|
496 | |
---|
497 | /** |
---|
498 | * Fires after PHPMailer is initialized. |
---|
499 | * |
---|
500 | * @since 2.2.0 |
---|
501 | * |
---|
502 | * @param PHPMailer &$phpmailer The PHPMailer instance, passed by reference. |
---|
503 | */ |
---|
504 | do_action_ref_array( 'phpmailer_init', array( &$phpmailer ) ); |
---|
505 | |
---|
506 | // Send! |
---|
507 | try { |
---|
508 | return $phpmailer->Send(); |
---|
509 | } catch ( phpmailerException $e ) { |
---|
510 | return false; |
---|
511 | } |
---|
512 | } |
---|
513 | endif; |
---|
514 | |
---|
515 | if ( !function_exists('wp_authenticate') ) : |
---|
516 | /** |
---|
517 | * Checks a user's login information and logs them in if it checks out. |
---|
518 | * |
---|
519 | * @since 2.5.0 |
---|
520 | * |
---|
521 | * @param string $username User's username |
---|
522 | * @param string $password User's password |
---|
523 | * @return WP_User|WP_Error WP_User object if login successful, otherwise WP_Error object. |
---|
524 | */ |
---|
525 | function wp_authenticate($username, $password) { |
---|
526 | $username = sanitize_user($username); |
---|
527 | $password = trim($password); |
---|
528 | |
---|
529 | /** |
---|
530 | * Filter the user to authenticate. |
---|
531 | * |
---|
532 | * If a non-null value is passed, the filter will effectively short-circuit |
---|
533 | * authentication, returning an error instead. |
---|
534 | * |
---|
535 | * @since 2.8.0 |
---|
536 | * |
---|
537 | * @param null|WP_User $user User to authenticate. |
---|
538 | * @param string $username User login. |
---|
539 | * @param string $password User password |
---|
540 | */ |
---|
541 | $user = apply_filters( 'authenticate', null, $username, $password ); |
---|
542 | |
---|
543 | if ( $user == null ) { |
---|
544 | // TODO what should the error message be? (Or would these even happen?) |
---|
545 | // Only needed if all authentication handlers fail to return anything. |
---|
546 | $user = new WP_Error('authentication_failed', __('<strong>ERROR</strong>: Invalid username or incorrect password.')); |
---|
547 | } |
---|
548 | |
---|
549 | $ignore_codes = array('empty_username', 'empty_password'); |
---|
550 | |
---|
551 | if (is_wp_error($user) && !in_array($user->get_error_code(), $ignore_codes) ) { |
---|
552 | /** |
---|
553 | * Fires after a user login has failed. |
---|
554 | * |
---|
555 | * @since 2.5.0 |
---|
556 | * |
---|
557 | * @param string $username User login. |
---|
558 | */ |
---|
559 | do_action( 'wp_login_failed', $username ); |
---|
560 | } |
---|
561 | |
---|
562 | return $user; |
---|
563 | } |
---|
564 | endif; |
---|
565 | |
---|
566 | if ( !function_exists('wp_logout') ) : |
---|
567 | /** |
---|
568 | * Log the current user out. |
---|
569 | * |
---|
570 | * @since 2.5.0 |
---|
571 | */ |
---|
572 | function wp_logout() { |
---|
573 | wp_clear_auth_cookie(); |
---|
574 | |
---|
575 | /** |
---|
576 | * Fires after a user is logged-out. |
---|
577 | * |
---|
578 | * @since 1.5.0 |
---|
579 | */ |
---|
580 | do_action( 'wp_logout' ); |
---|
581 | } |
---|
582 | endif; |
---|
583 | |
---|
584 | if ( !function_exists('wp_validate_auth_cookie') ) : |
---|
585 | /** |
---|
586 | * Validates authentication cookie. |
---|
587 | * |
---|
588 | * The checks include making sure that the authentication cookie is set and |
---|
589 | * pulling in the contents (if $cookie is not used). |
---|
590 | * |
---|
591 | * Makes sure the cookie is not expired. Verifies the hash in cookie is what is |
---|
592 | * should be and compares the two. |
---|
593 | * |
---|
594 | * @since 2.5.0 |
---|
595 | * |
---|
596 | * @param string $cookie Optional. If used, will validate contents instead of cookie's |
---|
597 | * @param string $scheme Optional. The cookie scheme to use: auth, secure_auth, or logged_in |
---|
598 | * @return bool|int False if invalid cookie, User ID if valid. |
---|
599 | */ |
---|
600 | function wp_validate_auth_cookie($cookie = '', $scheme = '') { |
---|
601 | if ( ! $cookie_elements = wp_parse_auth_cookie($cookie, $scheme) ) { |
---|
602 | /** |
---|
603 | * Fires if an authentication cookie is malformed. |
---|
604 | * |
---|
605 | * @since 2.7.0 |
---|
606 | * |
---|
607 | * @param string $cookie Malformed auth cookie. |
---|
608 | * @param string $scheme Authentication scheme. Values include 'auth', 'secure_auth', |
---|
609 | * or 'logged_in'. |
---|
610 | */ |
---|
611 | do_action( 'auth_cookie_malformed', $cookie, $scheme ); |
---|
612 | return false; |
---|
613 | } |
---|
614 | |
---|
615 | extract($cookie_elements, EXTR_OVERWRITE); |
---|
616 | |
---|
617 | $expired = $expiration; |
---|
618 | |
---|
619 | // Allow a grace period for POST and AJAX requests |
---|
620 | if ( defined('DOING_AJAX') || 'POST' == $_SERVER['REQUEST_METHOD'] ) |
---|
621 | $expired += HOUR_IN_SECONDS; |
---|
622 | |
---|
623 | // Quick check to see if an honest cookie has expired |
---|
624 | if ( $expired < time() ) { |
---|
625 | /** |
---|
626 | * Fires once an authentication cookie has expired. |
---|
627 | * |
---|
628 | * @since 2.7.0 |
---|
629 | * |
---|
630 | * @param array $cookie_elements An array of data for the authentication cookie. |
---|
631 | */ |
---|
632 | do_action( 'auth_cookie_expired', $cookie_elements ); |
---|
633 | return false; |
---|
634 | } |
---|
635 | |
---|
636 | $user = get_user_by('login', $username); |
---|
637 | if ( ! $user ) { |
---|
638 | /** |
---|
639 | * Fires if a bad username is entered in the user authentication process. |
---|
640 | * |
---|
641 | * @since 2.7.0 |
---|
642 | * |
---|
643 | * @param array $cookie_elements An array of data for the authentication cookie. |
---|
644 | */ |
---|
645 | do_action( 'auth_cookie_bad_username', $cookie_elements ); |
---|
646 | return false; |
---|
647 | } |
---|
648 | |
---|
649 | $pass_frag = substr($user->user_pass, 8, 4); |
---|
650 | |
---|
651 | $key = wp_hash($username . $pass_frag . '|' . $expiration, $scheme); |
---|
652 | $hash = hash_hmac('md5', $username . '|' . $expiration, $key); |
---|
653 | |
---|
654 | if ( hash_hmac( 'md5', $hmac, $key ) !== hash_hmac( 'md5', $hash, $key ) ) { |
---|
655 | /** |
---|
656 | * Fires if a bad authentication cookie hash is encountered. |
---|
657 | * |
---|
658 | * @since 2.7.0 |
---|
659 | * |
---|
660 | * @param array $cookie_elements An array of data for the authentication cookie. |
---|
661 | */ |
---|
662 | do_action( 'auth_cookie_bad_hash', $cookie_elements ); |
---|
663 | return false; |
---|
664 | } |
---|
665 | |
---|
666 | if ( $expiration < time() ) // AJAX/POST grace period set above |
---|
667 | $GLOBALS['login_grace_period'] = 1; |
---|
668 | |
---|
669 | /** |
---|
670 | * Fires once an authentication cookie has been validated. |
---|
671 | * |
---|
672 | * @since 2.7.0 |
---|
673 | * |
---|
674 | * @param array $cookie_elements An array of data for the authentication cookie. |
---|
675 | * @param WP_User $user User object. |
---|
676 | */ |
---|
677 | do_action( 'auth_cookie_valid', $cookie_elements, $user ); |
---|
678 | |
---|
679 | return $user->ID; |
---|
680 | } |
---|
681 | endif; |
---|
682 | |
---|
683 | if ( !function_exists('wp_generate_auth_cookie') ) : |
---|
684 | /** |
---|
685 | * Generate authentication cookie contents. |
---|
686 | * |
---|
687 | * @since 2.5.0 |
---|
688 | * |
---|
689 | * @param int $user_id User ID |
---|
690 | * @param int $expiration Cookie expiration in seconds |
---|
691 | * @param string $scheme Optional. The cookie scheme to use: auth, secure_auth, or logged_in |
---|
692 | * @return string Authentication cookie contents |
---|
693 | */ |
---|
694 | function wp_generate_auth_cookie($user_id, $expiration, $scheme = 'auth') { |
---|
695 | $user = get_userdata($user_id); |
---|
696 | |
---|
697 | $pass_frag = substr($user->user_pass, 8, 4); |
---|
698 | |
---|
699 | $key = wp_hash($user->user_login . $pass_frag . '|' . $expiration, $scheme); |
---|
700 | $hash = hash_hmac('md5', $user->user_login . '|' . $expiration, $key); |
---|
701 | |
---|
702 | $cookie = $user->user_login . '|' . $expiration . '|' . $hash; |
---|
703 | |
---|
704 | /** |
---|
705 | * Filter the authentication cookie. |
---|
706 | * |
---|
707 | * @since 2.5.0 |
---|
708 | * |
---|
709 | * @param string $cookie Authentication cookie. |
---|
710 | * @param int $user_id User ID. |
---|
711 | * @param int $expiration Authentication cookie expiration in seconds. |
---|
712 | * @param string $scheme Cookie scheme used. Accepts 'auth', 'secure_auth', or 'logged_in'. |
---|
713 | */ |
---|
714 | return apply_filters( 'auth_cookie', $cookie, $user_id, $expiration, $scheme ); |
---|
715 | } |
---|
716 | endif; |
---|
717 | |
---|
718 | if ( !function_exists('wp_parse_auth_cookie') ) : |
---|
719 | /** |
---|
720 | * Parse a cookie into its components |
---|
721 | * |
---|
722 | * @since 2.7.0 |
---|
723 | * |
---|
724 | * @param string $cookie |
---|
725 | * @param string $scheme Optional. The cookie scheme to use: auth, secure_auth, or logged_in |
---|
726 | * @return array Authentication cookie components |
---|
727 | */ |
---|
728 | function wp_parse_auth_cookie($cookie = '', $scheme = '') { |
---|
729 | if ( empty($cookie) ) { |
---|
730 | switch ($scheme){ |
---|
731 | case 'auth': |
---|
732 | $cookie_name = AUTH_COOKIE; |
---|
733 | break; |
---|
734 | case 'secure_auth': |
---|
735 | $cookie_name = SECURE_AUTH_COOKIE; |
---|
736 | break; |
---|
737 | case "logged_in": |
---|
738 | $cookie_name = LOGGED_IN_COOKIE; |
---|
739 | break; |
---|
740 | default: |
---|
741 | if ( is_ssl() ) { |
---|
742 | $cookie_name = SECURE_AUTH_COOKIE; |
---|
743 | $scheme = 'secure_auth'; |
---|
744 | } else { |
---|
745 | $cookie_name = AUTH_COOKIE; |
---|
746 | $scheme = 'auth'; |
---|
747 | } |
---|
748 | } |
---|
749 | |
---|
750 | if ( empty($_COOKIE[$cookie_name]) ) |
---|
751 | return false; |
---|
752 | $cookie = $_COOKIE[$cookie_name]; |
---|
753 | } |
---|
754 | |
---|
755 | $cookie_elements = explode('|', $cookie); |
---|
756 | if ( count($cookie_elements) != 3 ) |
---|
757 | return false; |
---|
758 | |
---|
759 | list($username, $expiration, $hmac) = $cookie_elements; |
---|
760 | |
---|
761 | return compact('username', 'expiration', 'hmac', 'scheme'); |
---|
762 | } |
---|
763 | endif; |
---|
764 | |
---|
765 | if ( !function_exists('wp_set_auth_cookie') ) : |
---|
766 | /** |
---|
767 | * Sets the authentication cookies based on user ID. |
---|
768 | * |
---|
769 | * The $remember parameter increases the time that the cookie will be kept. The |
---|
770 | * default the cookie is kept without remembering is two days. When $remember is |
---|
771 | * set, the cookies will be kept for 14 days or two weeks. |
---|
772 | * |
---|
773 | * @since 2.5.0 |
---|
774 | * |
---|
775 | * @param int $user_id User ID |
---|
776 | * @param bool $remember Whether to remember the user |
---|
777 | */ |
---|
778 | function wp_set_auth_cookie($user_id, $remember = false, $secure = '') { |
---|
779 | if ( $remember ) { |
---|
780 | /** |
---|
781 | * Filter the duration of the authentication cookie expiration period. |
---|
782 | * |
---|
783 | * @since 2.8.0 |
---|
784 | * |
---|
785 | * @param int $length Duration of the expiration period in seconds. |
---|
786 | * @param int $user_id User ID. |
---|
787 | * @param bool $remember Whether to remember the user login. Default false. |
---|
788 | */ |
---|
789 | $expiration = time() + apply_filters( 'auth_cookie_expiration', 14 * DAY_IN_SECONDS, $user_id, $remember ); |
---|
790 | |
---|
791 | /* |
---|
792 | * Ensure the browser will continue to send the cookie after the expiration time is reached. |
---|
793 | * Needed for the login grace period in wp_validate_auth_cookie(). |
---|
794 | */ |
---|
795 | $expire = $expiration + ( 12 * HOUR_IN_SECONDS ); |
---|
796 | } else { |
---|
797 | /** This filter is documented in wp-includes/pluggable.php */ |
---|
798 | $expiration = time() + apply_filters( 'auth_cookie_expiration', 2 * DAY_IN_SECONDS, $user_id, $remember ); |
---|
799 | $expire = 0; |
---|
800 | } |
---|
801 | |
---|
802 | if ( '' === $secure ) |
---|
803 | $secure = is_ssl(); |
---|
804 | |
---|
805 | /** |
---|
806 | * Filter whether the connection is secure. |
---|
807 | * |
---|
808 | * @since 3.1.0 |
---|
809 | * |
---|
810 | * @param bool $secure Whether the connection is secure. |
---|
811 | * @param int $user_id User ID. |
---|
812 | */ |
---|
813 | $secure = apply_filters( 'secure_auth_cookie', $secure, $user_id ); |
---|
814 | |
---|
815 | /** |
---|
816 | * Filter whether to use a secure cookie when logged-in. |
---|
817 | * |
---|
818 | * @since 3.1.0 |
---|
819 | * |
---|
820 | * @param bool $cookie Whether to use a secure cookie when logged-in. |
---|
821 | * @param int $user_id User ID. |
---|
822 | * @param bool $secure Whether the connection is secure. |
---|
823 | */ |
---|
824 | $secure_logged_in_cookie = apply_filters( 'secure_logged_in_cookie', false, $user_id, $secure ); |
---|
825 | |
---|
826 | if ( $secure ) { |
---|
827 | $auth_cookie_name = SECURE_AUTH_COOKIE; |
---|
828 | $scheme = 'secure_auth'; |
---|
829 | } else { |
---|
830 | $auth_cookie_name = AUTH_COOKIE; |
---|
831 | $scheme = 'auth'; |
---|
832 | } |
---|
833 | |
---|
834 | $auth_cookie = wp_generate_auth_cookie($user_id, $expiration, $scheme); |
---|
835 | $logged_in_cookie = wp_generate_auth_cookie($user_id, $expiration, 'logged_in'); |
---|
836 | |
---|
837 | /** |
---|
838 | * Fires immediately before the authentication cookie is set. |
---|
839 | * |
---|
840 | * @since 2.5.0 |
---|
841 | * |
---|
842 | * @param string $auth_cookie Authentication cookie. |
---|
843 | * @param int $expire Login grace period in seconds. Default 43,200 seconds, or 12 hours. |
---|
844 | * @param int $expiration Duration in seconds the authentication cookie should be valid. |
---|
845 | * Default 1,209,600 seconds, or 14 days. |
---|
846 | * @param int $user_id User ID. |
---|
847 | * @param string $scheme Authentication scheme. Values include 'auth', 'secure_auth', or 'logged_in'. |
---|
848 | */ |
---|
849 | do_action( 'set_auth_cookie', $auth_cookie, $expire, $expiration, $user_id, $scheme ); |
---|
850 | |
---|
851 | /** |
---|
852 | * Fires immediately before the secure authentication cookie is set. |
---|
853 | * |
---|
854 | * @since 2.6.0 |
---|
855 | * |
---|
856 | * @param string $logged_in_cookie The logged-in cookie. |
---|
857 | * @param int $expire Login grace period in seconds. Default 43,200 seconds, or 12 hours. |
---|
858 | * @param int $expiration Duration in seconds the authentication cookie should be valid. |
---|
859 | * Default 1,209,600 seconds, or 14 days. |
---|
860 | * @param int $user_id User ID. |
---|
861 | * @param string $scheme Authentication scheme. Default 'logged_in'. |
---|
862 | */ |
---|
863 | do_action( 'set_logged_in_cookie', $logged_in_cookie, $expire, $expiration, $user_id, 'logged_in' ); |
---|
864 | |
---|
865 | setcookie($auth_cookie_name, $auth_cookie, $expire, PLUGINS_COOKIE_PATH, COOKIE_DOMAIN, $secure, true); |
---|
866 | setcookie($auth_cookie_name, $auth_cookie, $expire, ADMIN_COOKIE_PATH, COOKIE_DOMAIN, $secure, true); |
---|
867 | setcookie(LOGGED_IN_COOKIE, $logged_in_cookie, $expire, COOKIEPATH, COOKIE_DOMAIN, $secure_logged_in_cookie, true); |
---|
868 | if ( COOKIEPATH != SITECOOKIEPATH ) |
---|
869 | setcookie(LOGGED_IN_COOKIE, $logged_in_cookie, $expire, SITECOOKIEPATH, COOKIE_DOMAIN, $secure_logged_in_cookie, true); |
---|
870 | } |
---|
871 | endif; |
---|
872 | |
---|
873 | if ( !function_exists('wp_clear_auth_cookie') ) : |
---|
874 | /** |
---|
875 | * Removes all of the cookies associated with authentication. |
---|
876 | * |
---|
877 | * @since 2.5.0 |
---|
878 | */ |
---|
879 | function wp_clear_auth_cookie() { |
---|
880 | /** |
---|
881 | * Fires just before the authentication cookies are cleared. |
---|
882 | * |
---|
883 | * @since 2.7.0 |
---|
884 | */ |
---|
885 | do_action( 'clear_auth_cookie' ); |
---|
886 | |
---|
887 | setcookie( AUTH_COOKIE, ' ', time() - YEAR_IN_SECONDS, ADMIN_COOKIE_PATH, COOKIE_DOMAIN ); |
---|
888 | setcookie( SECURE_AUTH_COOKIE, ' ', time() - YEAR_IN_SECONDS, ADMIN_COOKIE_PATH, COOKIE_DOMAIN ); |
---|
889 | setcookie( AUTH_COOKIE, ' ', time() - YEAR_IN_SECONDS, PLUGINS_COOKIE_PATH, COOKIE_DOMAIN ); |
---|
890 | setcookie( SECURE_AUTH_COOKIE, ' ', time() - YEAR_IN_SECONDS, PLUGINS_COOKIE_PATH, COOKIE_DOMAIN ); |
---|
891 | setcookie( LOGGED_IN_COOKIE, ' ', time() - YEAR_IN_SECONDS, COOKIEPATH, COOKIE_DOMAIN ); |
---|
892 | setcookie( LOGGED_IN_COOKIE, ' ', time() - YEAR_IN_SECONDS, SITECOOKIEPATH, COOKIE_DOMAIN ); |
---|
893 | |
---|
894 | // Old cookies |
---|
895 | setcookie( AUTH_COOKIE, ' ', time() - YEAR_IN_SECONDS, COOKIEPATH, COOKIE_DOMAIN ); |
---|
896 | setcookie( AUTH_COOKIE, ' ', time() - YEAR_IN_SECONDS, SITECOOKIEPATH, COOKIE_DOMAIN ); |
---|
897 | setcookie( SECURE_AUTH_COOKIE, ' ', time() - YEAR_IN_SECONDS, COOKIEPATH, COOKIE_DOMAIN ); |
---|
898 | setcookie( SECURE_AUTH_COOKIE, ' ', time() - YEAR_IN_SECONDS, SITECOOKIEPATH, COOKIE_DOMAIN ); |
---|
899 | |
---|
900 | // Even older cookies |
---|
901 | setcookie( USER_COOKIE, ' ', time() - YEAR_IN_SECONDS, COOKIEPATH, COOKIE_DOMAIN ); |
---|
902 | setcookie( PASS_COOKIE, ' ', time() - YEAR_IN_SECONDS, COOKIEPATH, COOKIE_DOMAIN ); |
---|
903 | setcookie( USER_COOKIE, ' ', time() - YEAR_IN_SECONDS, SITECOOKIEPATH, COOKIE_DOMAIN ); |
---|
904 | setcookie( PASS_COOKIE, ' ', time() - YEAR_IN_SECONDS, SITECOOKIEPATH, COOKIE_DOMAIN ); |
---|
905 | } |
---|
906 | endif; |
---|
907 | |
---|
908 | if ( !function_exists('is_user_logged_in') ) : |
---|
909 | /** |
---|
910 | * Checks if the current visitor is a logged in user. |
---|
911 | * |
---|
912 | * @since 2.0.0 |
---|
913 | * |
---|
914 | * @return bool True if user is logged in, false if not logged in. |
---|
915 | */ |
---|
916 | function is_user_logged_in() { |
---|
917 | $user = wp_get_current_user(); |
---|
918 | |
---|
919 | if ( ! $user->exists() ) |
---|
920 | return false; |
---|
921 | |
---|
922 | return true; |
---|
923 | } |
---|
924 | endif; |
---|
925 | |
---|
926 | if ( !function_exists('auth_redirect') ) : |
---|
927 | /** |
---|
928 | * Checks if a user is logged in, if not it redirects them to the login page. |
---|
929 | * |
---|
930 | * @since 1.5.0 |
---|
931 | */ |
---|
932 | function auth_redirect() { |
---|
933 | // Checks if a user is logged in, if not redirects them to the login page |
---|
934 | |
---|
935 | $secure = ( is_ssl() || force_ssl_admin() ); |
---|
936 | |
---|
937 | /** |
---|
938 | * Filter whether to use a secure authentication redirect. |
---|
939 | * |
---|
940 | * @since 3.1.0 |
---|
941 | * |
---|
942 | * @param bool $secure Whether to use a secure authentication redirect. Default false. |
---|
943 | */ |
---|
944 | $secure = apply_filters( 'secure_auth_redirect', $secure ); |
---|
945 | |
---|
946 | // If https is required and request is http, redirect |
---|
947 | if ( $secure && !is_ssl() && false !== strpos($_SERVER['REQUEST_URI'], 'wp-admin') ) { |
---|
948 | if ( 0 === strpos( $_SERVER['REQUEST_URI'], 'http' ) ) { |
---|
949 | wp_redirect( set_url_scheme( $_SERVER['REQUEST_URI'], 'https' ) ); |
---|
950 | exit(); |
---|
951 | } else { |
---|
952 | wp_redirect( 'https://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] ); |
---|
953 | exit(); |
---|
954 | } |
---|
955 | } |
---|
956 | |
---|
957 | if ( is_user_admin() ) { |
---|
958 | $scheme = 'logged_in'; |
---|
959 | } else { |
---|
960 | /** |
---|
961 | * Filter the authentication redirect scheme. |
---|
962 | * |
---|
963 | * @since 2.9.0 |
---|
964 | * |
---|
965 | * @param string $scheme Authentication redirect scheme. Default empty. |
---|
966 | */ |
---|
967 | $scheme = apply_filters( 'auth_redirect_scheme', '' ); |
---|
968 | } |
---|
969 | |
---|
970 | if ( $user_id = wp_validate_auth_cookie( '', $scheme) ) { |
---|
971 | /** |
---|
972 | * Fires before the authentication redirect. |
---|
973 | * |
---|
974 | * @since 2.8.0 |
---|
975 | * |
---|
976 | * @param int $user_id User ID. |
---|
977 | */ |
---|
978 | do_action( 'auth_redirect', $user_id ); |
---|
979 | |
---|
980 | // If the user wants ssl but the session is not ssl, redirect. |
---|
981 | if ( !$secure && get_user_option('use_ssl', $user_id) && false !== strpos($_SERVER['REQUEST_URI'], 'wp-admin') ) { |
---|
982 | if ( 0 === strpos( $_SERVER['REQUEST_URI'], 'http' ) ) { |
---|
983 | wp_redirect( set_url_scheme( $_SERVER['REQUEST_URI'], 'https' ) ); |
---|
984 | exit(); |
---|
985 | } else { |
---|
986 | wp_redirect( 'https://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] ); |
---|
987 | exit(); |
---|
988 | } |
---|
989 | } |
---|
990 | |
---|
991 | return; // The cookie is good so we're done |
---|
992 | } |
---|
993 | |
---|
994 | // The cookie is no good so force login |
---|
995 | nocache_headers(); |
---|
996 | |
---|
997 | $redirect = ( strpos( $_SERVER['REQUEST_URI'], '/options.php' ) && wp_get_referer() ) ? wp_get_referer() : set_url_scheme( 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] ); |
---|
998 | |
---|
999 | $login_url = wp_login_url($redirect, true); |
---|
1000 | |
---|
1001 | wp_redirect($login_url); |
---|
1002 | exit(); |
---|
1003 | } |
---|
1004 | endif; |
---|
1005 | |
---|
1006 | if ( !function_exists('check_admin_referer') ) : |
---|
1007 | /** |
---|
1008 | * Makes sure that a user was referred from another admin page. |
---|
1009 | * |
---|
1010 | * To avoid security exploits. |
---|
1011 | * |
---|
1012 | * @since 1.2.0 |
---|
1013 | * |
---|
1014 | * @param string $action Action nonce |
---|
1015 | * @param string $query_arg where to look for nonce in $_REQUEST (since 2.5) |
---|
1016 | */ |
---|
1017 | function check_admin_referer($action = -1, $query_arg = '_wpnonce') { |
---|
1018 | if ( -1 == $action ) |
---|
1019 | _doing_it_wrong( __FUNCTION__, __( 'You should specify a nonce action to be verified by using the first parameter.' ), '3.2' ); |
---|
1020 | |
---|
1021 | $adminurl = strtolower(admin_url()); |
---|
1022 | $referer = strtolower(wp_get_referer()); |
---|
1023 | $result = isset($_REQUEST[$query_arg]) ? wp_verify_nonce($_REQUEST[$query_arg], $action) : false; |
---|
1024 | if ( !$result && !(-1 == $action && strpos($referer, $adminurl) === 0) ) { |
---|
1025 | wp_nonce_ays($action); |
---|
1026 | die(); |
---|
1027 | } |
---|
1028 | |
---|
1029 | /** |
---|
1030 | * Fires once the admin request has been validated or not. |
---|
1031 | * |
---|
1032 | * @since 1.5.1 |
---|
1033 | * |
---|
1034 | * @param string $action The nonce action. |
---|
1035 | * @param bool $result Whether the admin request nonce was validated. |
---|
1036 | */ |
---|
1037 | do_action( 'check_admin_referer', $action, $result ); |
---|
1038 | return $result; |
---|
1039 | } |
---|
1040 | endif; |
---|
1041 | |
---|
1042 | if ( !function_exists('check_ajax_referer') ) : |
---|
1043 | /** |
---|
1044 | * Verifies the AJAX request to prevent processing requests external of the blog. |
---|
1045 | * |
---|
1046 | * @since 2.0.3 |
---|
1047 | * |
---|
1048 | * @param string $action Action nonce |
---|
1049 | * @param string $query_arg where to look for nonce in $_REQUEST (since 2.5) |
---|
1050 | */ |
---|
1051 | function check_ajax_referer( $action = -1, $query_arg = false, $die = true ) { |
---|
1052 | $nonce = ''; |
---|
1053 | |
---|
1054 | if ( $query_arg && isset( $_REQUEST[ $query_arg ] ) ) |
---|
1055 | $nonce = $_REQUEST[ $query_arg ]; |
---|
1056 | elseif ( isset( $_REQUEST['_ajax_nonce'] ) ) |
---|
1057 | $nonce = $_REQUEST['_ajax_nonce']; |
---|
1058 | elseif ( isset( $_REQUEST['_wpnonce'] ) ) |
---|
1059 | $nonce = $_REQUEST['_wpnonce']; |
---|
1060 | |
---|
1061 | $result = wp_verify_nonce( $nonce, $action ); |
---|
1062 | |
---|
1063 | if ( $die && false == $result ) { |
---|
1064 | if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) |
---|
1065 | wp_die( -1 ); |
---|
1066 | else |
---|
1067 | die( '-1' ); |
---|
1068 | } |
---|
1069 | |
---|
1070 | /** |
---|
1071 | * Fires once the AJAX request has been validated or not. |
---|
1072 | * |
---|
1073 | * @since 2.1.0 |
---|
1074 | * |
---|
1075 | * @param string $action The AJAX nonce action. |
---|
1076 | * @param bool $result Whether the AJAX request nonce was validated. |
---|
1077 | */ |
---|
1078 | do_action( 'check_ajax_referer', $action, $result ); |
---|
1079 | |
---|
1080 | return $result; |
---|
1081 | } |
---|
1082 | endif; |
---|
1083 | |
---|
1084 | if ( !function_exists('wp_redirect') ) : |
---|
1085 | /** |
---|
1086 | * Redirects to another page. |
---|
1087 | * |
---|
1088 | * @since 1.5.1 |
---|
1089 | * |
---|
1090 | * @param string $location The path to redirect to. |
---|
1091 | * @param int $status Status code to use. |
---|
1092 | * @return bool False if $location is not provided, true otherwise. |
---|
1093 | */ |
---|
1094 | function wp_redirect($location, $status = 302) { |
---|
1095 | global $is_IIS; |
---|
1096 | |
---|
1097 | /** |
---|
1098 | * Filter the redirect location. |
---|
1099 | * |
---|
1100 | * @since 2.1.0 |
---|
1101 | * |
---|
1102 | * @param string $location The path to redirect to. |
---|
1103 | * @param int $status Status code to use. |
---|
1104 | */ |
---|
1105 | $location = apply_filters( 'wp_redirect', $location, $status ); |
---|
1106 | |
---|
1107 | /** |
---|
1108 | * Filter the redirect status code. |
---|
1109 | * |
---|
1110 | * @since 2.3.0 |
---|
1111 | * |
---|
1112 | * @param int $status Status code to use. |
---|
1113 | * @param string $location The path to redirect to. |
---|
1114 | */ |
---|
1115 | $status = apply_filters( 'wp_redirect_status', $status, $location ); |
---|
1116 | |
---|
1117 | if ( ! $location ) |
---|
1118 | return false; |
---|
1119 | |
---|
1120 | $location = wp_sanitize_redirect($location); |
---|
1121 | |
---|
1122 | if ( !$is_IIS && php_sapi_name() != 'cgi-fcgi' ) |
---|
1123 | status_header($status); // This causes problems on IIS and some FastCGI setups |
---|
1124 | |
---|
1125 | header("Location: $location", true, $status); |
---|
1126 | |
---|
1127 | return true; |
---|
1128 | } |
---|
1129 | endif; |
---|
1130 | |
---|
1131 | if ( !function_exists('wp_sanitize_redirect') ) : |
---|
1132 | /** |
---|
1133 | * Sanitizes a URL for use in a redirect. |
---|
1134 | * |
---|
1135 | * @since 2.3.0 |
---|
1136 | * |
---|
1137 | * @return string redirect-sanitized URL |
---|
1138 | **/ |
---|
1139 | function wp_sanitize_redirect($location) { |
---|
1140 | $location = preg_replace('|[^a-z0-9-~+_.?#=&;,/:%!]|i', '', $location); |
---|
1141 | $location = wp_kses_no_null($location); |
---|
1142 | |
---|
1143 | // remove %0d and %0a from location |
---|
1144 | $strip = array('%0d', '%0a', '%0D', '%0A'); |
---|
1145 | $location = _deep_replace($strip, $location); |
---|
1146 | return $location; |
---|
1147 | } |
---|
1148 | endif; |
---|
1149 | |
---|
1150 | if ( !function_exists('wp_safe_redirect') ) : |
---|
1151 | /** |
---|
1152 | * Performs a safe (local) redirect, using wp_redirect(). |
---|
1153 | * |
---|
1154 | * Checks whether the $location is using an allowed host, if it has an absolute |
---|
1155 | * path. A plugin can therefore set or remove allowed host(s) to or from the |
---|
1156 | * list. |
---|
1157 | * |
---|
1158 | * If the host is not allowed, then the redirect is to wp-admin on the siteurl |
---|
1159 | * instead. This prevents malicious redirects which redirect to another host, |
---|
1160 | * but only used in a few places. |
---|
1161 | * |
---|
1162 | * @since 2.3.0 |
---|
1163 | * |
---|
1164 | * @uses wp_validate_redirect() To validate the redirect is to an allowed host. |
---|
1165 | * |
---|
1166 | * @return void Does not return anything |
---|
1167 | **/ |
---|
1168 | function wp_safe_redirect($location, $status = 302) { |
---|
1169 | |
---|
1170 | // Need to look at the URL the way it will end up in wp_redirect() |
---|
1171 | $location = wp_sanitize_redirect($location); |
---|
1172 | |
---|
1173 | $location = wp_validate_redirect($location, admin_url()); |
---|
1174 | |
---|
1175 | wp_redirect($location, $status); |
---|
1176 | } |
---|
1177 | endif; |
---|
1178 | |
---|
1179 | if ( !function_exists('wp_validate_redirect') ) : |
---|
1180 | /** |
---|
1181 | * Validates a URL for use in a redirect. |
---|
1182 | * |
---|
1183 | * Checks whether the $location is using an allowed host, if it has an absolute |
---|
1184 | * path. A plugin can therefore set or remove allowed host(s) to or from the |
---|
1185 | * list. |
---|
1186 | * |
---|
1187 | * If the host is not allowed, then the redirect is to $default supplied |
---|
1188 | * |
---|
1189 | * @since 2.8.1 |
---|
1190 | * |
---|
1191 | * @param string $location The redirect to validate |
---|
1192 | * @param string $default The value to return if $location is not allowed |
---|
1193 | * @return string redirect-sanitized URL |
---|
1194 | **/ |
---|
1195 | function wp_validate_redirect($location, $default = '') { |
---|
1196 | $location = trim( $location ); |
---|
1197 | // browsers will assume 'http' is your protocol, and will obey a redirect to a URL starting with '//' |
---|
1198 | if ( substr($location, 0, 2) == '//' ) |
---|
1199 | $location = 'http:' . $location; |
---|
1200 | |
---|
1201 | // In php 5 parse_url may fail if the URL query part contains http://, bug #38143 |
---|
1202 | $test = ( $cut = strpos($location, '?') ) ? substr( $location, 0, $cut ) : $location; |
---|
1203 | |
---|
1204 | $lp = parse_url($test); |
---|
1205 | |
---|
1206 | // Give up if malformed URL |
---|
1207 | if ( false === $lp ) |
---|
1208 | return $default; |
---|
1209 | |
---|
1210 | // Allow only http and https schemes. No data:, etc. |
---|
1211 | if ( isset($lp['scheme']) && !('http' == $lp['scheme'] || 'https' == $lp['scheme']) ) |
---|
1212 | return $default; |
---|
1213 | |
---|
1214 | // Reject if scheme is set but host is not. This catches urls like https:host.com for which parse_url does not set the host field. |
---|
1215 | if ( isset($lp['scheme']) && !isset($lp['host']) ) |
---|
1216 | return $default; |
---|
1217 | |
---|
1218 | $wpp = parse_url(home_url()); |
---|
1219 | |
---|
1220 | /** |
---|
1221 | * Filter the whitelist of hosts to redirect to. |
---|
1222 | * |
---|
1223 | * @since 2.3.0 |
---|
1224 | * |
---|
1225 | * @param array $hosts An array of allowed hosts. |
---|
1226 | * @param bool|string $host The parsed host; empty if not isset. |
---|
1227 | */ |
---|
1228 | $allowed_hosts = (array) apply_filters( 'allowed_redirect_hosts', array($wpp['host']), isset($lp['host']) ? $lp['host'] : '' ); |
---|
1229 | |
---|
1230 | if ( isset($lp['host']) && ( !in_array($lp['host'], $allowed_hosts) && $lp['host'] != strtolower($wpp['host'])) ) |
---|
1231 | $location = $default; |
---|
1232 | |
---|
1233 | return $location; |
---|
1234 | } |
---|
1235 | endif; |
---|
1236 | |
---|
1237 | if ( ! function_exists('wp_notify_postauthor') ) : |
---|
1238 | /** |
---|
1239 | * Notify an author (and/or others) of a comment/trackback/pingback on a post. |
---|
1240 | * |
---|
1241 | * @since 1.0.0 |
---|
1242 | * |
---|
1243 | * @param int $comment_id Comment ID |
---|
1244 | * @param string $deprecated Not used |
---|
1245 | * @return bool True on completion. False if no email addresses were specified. |
---|
1246 | */ |
---|
1247 | function wp_notify_postauthor( $comment_id, $deprecated = null ) { |
---|
1248 | if ( null !== $deprecated ) { |
---|
1249 | _deprecated_argument( __FUNCTION__, '3.8' ); |
---|
1250 | } |
---|
1251 | |
---|
1252 | $comment = get_comment( $comment_id ); |
---|
1253 | if ( empty( $comment ) ) |
---|
1254 | return false; |
---|
1255 | |
---|
1256 | $post = get_post( $comment->comment_post_ID ); |
---|
1257 | $author = get_userdata( $post->post_author ); |
---|
1258 | |
---|
1259 | // Who to notify? By default, just the post author, but others can be added. |
---|
1260 | $emails = array(); |
---|
1261 | if ( $author ) { |
---|
1262 | $emails[] = $author->user_email; |
---|
1263 | } |
---|
1264 | |
---|
1265 | /** |
---|
1266 | * Filter the list of email addresses to receive a comment notification. |
---|
1267 | * |
---|
1268 | * By default, only post authors are notified of comments. This filter allows |
---|
1269 | * others to be added. |
---|
1270 | * |
---|
1271 | * @since 3.7.0 |
---|
1272 | * |
---|
1273 | * @param array $emails An array of email addresses to receive a comment notification. |
---|
1274 | * @param int $comment_id The comment ID. |
---|
1275 | */ |
---|
1276 | $emails = apply_filters( 'comment_notification_recipients', $emails, $comment_id ); |
---|
1277 | $emails = array_filter( $emails ); |
---|
1278 | |
---|
1279 | // If there are no addresses to send the comment to, bail. |
---|
1280 | if ( ! count( $emails ) ) { |
---|
1281 | return false; |
---|
1282 | } |
---|
1283 | |
---|
1284 | // Facilitate unsetting below without knowing the keys. |
---|
1285 | $emails = array_flip( $emails ); |
---|
1286 | |
---|
1287 | /** |
---|
1288 | * Filter whether to notify comment authors of their comments on their own posts. |
---|
1289 | * |
---|
1290 | * By default, comment authors aren't notified of their comments on their own |
---|
1291 | * posts. This filter allows you to override that. |
---|
1292 | * |
---|
1293 | * @since 3.8.0 |
---|
1294 | * |
---|
1295 | * @param bool $notify Whether to notify the post author of their own comment. |
---|
1296 | * Default false. |
---|
1297 | * @param int $comment_id The comment ID. |
---|
1298 | */ |
---|
1299 | $notify_author = apply_filters( 'comment_notification_notify_author', false, $comment_id ); |
---|
1300 | |
---|
1301 | // The comment was left by the author |
---|
1302 | if ( $author && ! $notify_author && $comment->user_id == $post->post_author ) { |
---|
1303 | unset( $emails[ $author->user_email ] ); |
---|
1304 | } |
---|
1305 | |
---|
1306 | // The author moderated a comment on their own post |
---|
1307 | if ( $author && ! $notify_author && $post->post_author == get_current_user_id() ) { |
---|
1308 | unset( $emails[ $author->user_email ] ); |
---|
1309 | } |
---|
1310 | |
---|
1311 | // The post author is no longer a member of the blog |
---|
1312 | if ( $author && ! $notify_author && ! user_can( $post->post_author, 'read_post', $post->ID ) ) { |
---|
1313 | unset( $emails[ $author->user_email ] ); |
---|
1314 | } |
---|
1315 | |
---|
1316 | // If there's no email to send the comment to, bail, otherwise flip array back around for use below |
---|
1317 | if ( ! count( $emails ) ) { |
---|
1318 | return false; |
---|
1319 | } else { |
---|
1320 | $emails = array_flip( $emails ); |
---|
1321 | } |
---|
1322 | |
---|
1323 | $comment_author_domain = @gethostbyaddr($comment->comment_author_IP); |
---|
1324 | |
---|
1325 | // The blogname option is escaped with esc_html on the way into the database in sanitize_option |
---|
1326 | // we want to reverse this for the plain text arena of emails. |
---|
1327 | $blogname = wp_specialchars_decode(get_option('blogname'), ENT_QUOTES); |
---|
1328 | |
---|
1329 | switch ( $comment->comment_type ) { |
---|
1330 | case 'trackback': |
---|
1331 | $notify_message = sprintf( __( 'New trackback on your post "%s"' ), $post->post_title ) . "\r\n"; |
---|
1332 | /* translators: 1: website name, 2: author IP, 3: author domain */ |
---|
1333 | $notify_message .= sprintf( __('Website: %1$s (IP: %2$s , %3$s)'), $comment->comment_author, $comment->comment_author_IP, $comment_author_domain ) . "\r\n"; |
---|
1334 | $notify_message .= sprintf( __('URL : %s'), $comment->comment_author_url ) . "\r\n"; |
---|
1335 | $notify_message .= __('Excerpt: ') . "\r\n" . $comment->comment_content . "\r\n\r\n"; |
---|
1336 | $notify_message .= __('You can see all trackbacks on this post here: ') . "\r\n"; |
---|
1337 | /* translators: 1: blog name, 2: post title */ |
---|
1338 | $subject = sprintf( __('[%1$s] Trackback: "%2$s"'), $blogname, $post->post_title ); |
---|
1339 | break; |
---|
1340 | case 'pingback': |
---|
1341 | $notify_message = sprintf( __( 'New pingback on your post "%s"' ), $post->post_title ) . "\r\n"; |
---|
1342 | /* translators: 1: comment author, 2: author IP, 3: author domain */ |
---|
1343 | $notify_message .= sprintf( __('Website: %1$s (IP: %2$s , %3$s)'), $comment->comment_author, $comment->comment_author_IP, $comment_author_domain ) . "\r\n"; |
---|
1344 | $notify_message .= sprintf( __('URL : %s'), $comment->comment_author_url ) . "\r\n"; |
---|
1345 | $notify_message .= __('Excerpt: ') . "\r\n" . sprintf('[...] %s [...]', $comment->comment_content ) . "\r\n\r\n"; |
---|
1346 | $notify_message .= __('You can see all pingbacks on this post here: ') . "\r\n"; |
---|
1347 | /* translators: 1: blog name, 2: post title */ |
---|
1348 | $subject = sprintf( __('[%1$s] Pingback: "%2$s"'), $blogname, $post->post_title ); |
---|
1349 | break; |
---|
1350 | default: // Comments |
---|
1351 | $notify_message = sprintf( __( 'New comment on your post "%s"' ), $post->post_title ) . "\r\n"; |
---|
1352 | /* translators: 1: comment author, 2: author IP, 3: author domain */ |
---|
1353 | $notify_message .= sprintf( __('Author : %1$s (IP: %2$s , %3$s)'), $comment->comment_author, $comment->comment_author_IP, $comment_author_domain ) . "\r\n"; |
---|
1354 | $notify_message .= sprintf( __('E-mail : %s'), $comment->comment_author_email ) . "\r\n"; |
---|
1355 | $notify_message .= sprintf( __('URL : %s'), $comment->comment_author_url ) . "\r\n"; |
---|
1356 | $notify_message .= sprintf( __('Whois : http://whois.arin.net/rest/ip/%s'), $comment->comment_author_IP ) . "\r\n"; |
---|
1357 | $notify_message .= __('Comment: ') . "\r\n" . $comment->comment_content . "\r\n\r\n"; |
---|
1358 | $notify_message .= __('You can see all comments on this post here: ') . "\r\n"; |
---|
1359 | /* translators: 1: blog name, 2: post title */ |
---|
1360 | $subject = sprintf( __('[%1$s] Comment: "%2$s"'), $blogname, $post->post_title ); |
---|
1361 | break; |
---|
1362 | } |
---|
1363 | $notify_message .= get_permalink($comment->comment_post_ID) . "#comments\r\n\r\n"; |
---|
1364 | $notify_message .= sprintf( __('Permalink: %s'), get_comment_link( $comment_id ) ) . "\r\n"; |
---|
1365 | |
---|
1366 | if ( user_can( $post->post_author, 'edit_comment', $comment_id ) ) { |
---|
1367 | if ( EMPTY_TRASH_DAYS ) |
---|
1368 | $notify_message .= sprintf( __('Trash it: %s'), admin_url("comment.php?action=trash&c=$comment_id") ) . "\r\n"; |
---|
1369 | else |
---|
1370 | $notify_message .= sprintf( __('Delete it: %s'), admin_url("comment.php?action=delete&c=$comment_id") ) . "\r\n"; |
---|
1371 | $notify_message .= sprintf( __('Spam it: %s'), admin_url("comment.php?action=spam&c=$comment_id") ) . "\r\n"; |
---|
1372 | } |
---|
1373 | |
---|
1374 | $wp_email = 'wordpress@' . preg_replace('#^www\.#', '', strtolower($_SERVER['SERVER_NAME'])); |
---|
1375 | |
---|
1376 | if ( '' == $comment->comment_author ) { |
---|
1377 | $from = "From: \"$blogname\" <$wp_email>"; |
---|
1378 | if ( '' != $comment->comment_author_email ) |
---|
1379 | $reply_to = "Reply-To: $comment->comment_author_email"; |
---|
1380 | } else { |
---|
1381 | $from = "From: \"$comment->comment_author\" <$wp_email>"; |
---|
1382 | if ( '' != $comment->comment_author_email ) |
---|
1383 | $reply_to = "Reply-To: \"$comment->comment_author_email\" <$comment->comment_author_email>"; |
---|
1384 | } |
---|
1385 | |
---|
1386 | $message_headers = "$from\n" |
---|
1387 | . "Content-Type: text/plain; charset=\"" . get_option('blog_charset') . "\"\n"; |
---|
1388 | |
---|
1389 | if ( isset($reply_to) ) |
---|
1390 | $message_headers .= $reply_to . "\n"; |
---|
1391 | |
---|
1392 | /** |
---|
1393 | * Filter the comment notification email text. |
---|
1394 | * |
---|
1395 | * @since 1.5.2 |
---|
1396 | * |
---|
1397 | * @param string $notify_message The comment notification email text. |
---|
1398 | * @param int $comment_id Comment ID. |
---|
1399 | */ |
---|
1400 | $notify_message = apply_filters( 'comment_notification_text', $notify_message, $comment_id ); |
---|
1401 | |
---|
1402 | /** |
---|
1403 | * Filter the comment notification email subject. |
---|
1404 | * |
---|
1405 | * @since 1.5.2 |
---|
1406 | * |
---|
1407 | * @param string $subject The comment notification email subject. |
---|
1408 | * @param int $comment_id Comment ID. |
---|
1409 | */ |
---|
1410 | $subject = apply_filters( 'comment_notification_subject', $subject, $comment_id ); |
---|
1411 | |
---|
1412 | /** |
---|
1413 | * Filter the comment notification email headers. |
---|
1414 | * |
---|
1415 | * @since 1.5.2 |
---|
1416 | * |
---|
1417 | * @param string $message_headers Headers for the comment notification email. |
---|
1418 | * @param int $comment_id Comment ID. |
---|
1419 | */ |
---|
1420 | $message_headers = apply_filters( 'comment_notification_headers', $message_headers, $comment_id ); |
---|
1421 | |
---|
1422 | foreach ( $emails as $email ) { |
---|
1423 | @wp_mail( $email, wp_specialchars_decode( $subject ), $notify_message, $message_headers ); |
---|
1424 | } |
---|
1425 | |
---|
1426 | return true; |
---|
1427 | } |
---|
1428 | endif; |
---|
1429 | |
---|
1430 | if ( !function_exists('wp_notify_moderator') ) : |
---|
1431 | /** |
---|
1432 | * Notifies the moderator of the blog about a new comment that is awaiting approval. |
---|
1433 | * |
---|
1434 | * @since 1.0.0 |
---|
1435 | * |
---|
1436 | * @uses $wpdb |
---|
1437 | * |
---|
1438 | * @param int $comment_id Comment ID |
---|
1439 | * @return bool Always returns true |
---|
1440 | */ |
---|
1441 | function wp_notify_moderator($comment_id) { |
---|
1442 | global $wpdb; |
---|
1443 | |
---|
1444 | if ( 0 == get_option( 'moderation_notify' ) ) |
---|
1445 | return true; |
---|
1446 | |
---|
1447 | $comment = get_comment($comment_id); |
---|
1448 | $post = get_post($comment->comment_post_ID); |
---|
1449 | $user = get_userdata( $post->post_author ); |
---|
1450 | // Send to the administration and to the post author if the author can modify the comment. |
---|
1451 | $emails = array( get_option( 'admin_email' ) ); |
---|
1452 | if ( user_can( $user->ID, 'edit_comment', $comment_id ) && ! empty( $user->user_email ) ) { |
---|
1453 | if ( 0 !== strcasecmp( $user->user_email, get_option( 'admin_email' ) ) ) |
---|
1454 | $emails[] = $user->user_email; |
---|
1455 | } |
---|
1456 | |
---|
1457 | $comment_author_domain = @gethostbyaddr($comment->comment_author_IP); |
---|
1458 | $comments_waiting = $wpdb->get_var("SELECT count(comment_ID) FROM $wpdb->comments WHERE comment_approved = '0'"); |
---|
1459 | |
---|
1460 | // The blogname option is escaped with esc_html on the way into the database in sanitize_option |
---|
1461 | // we want to reverse this for the plain text arena of emails. |
---|
1462 | $blogname = wp_specialchars_decode(get_option('blogname'), ENT_QUOTES); |
---|
1463 | |
---|
1464 | switch ( $comment->comment_type ) { |
---|
1465 | case 'trackback': |
---|
1466 | $notify_message = sprintf( __('A new trackback on the post "%s" is waiting for your approval'), $post->post_title ) . "\r\n"; |
---|
1467 | $notify_message .= get_permalink($comment->comment_post_ID) . "\r\n\r\n"; |
---|
1468 | $notify_message .= sprintf( __('Website : %1$s (IP: %2$s , %3$s)'), $comment->comment_author, $comment->comment_author_IP, $comment_author_domain ) . "\r\n"; |
---|
1469 | $notify_message .= sprintf( __('URL : %s'), $comment->comment_author_url ) . "\r\n"; |
---|
1470 | $notify_message .= __('Trackback excerpt: ') . "\r\n" . $comment->comment_content . "\r\n\r\n"; |
---|
1471 | break; |
---|
1472 | case 'pingback': |
---|
1473 | $notify_message = sprintf( __('A new pingback on the post "%s" is waiting for your approval'), $post->post_title ) . "\r\n"; |
---|
1474 | $notify_message .= get_permalink($comment->comment_post_ID) . "\r\n\r\n"; |
---|
1475 | $notify_message .= sprintf( __('Website : %1$s (IP: %2$s , %3$s)'), $comment->comment_author, $comment->comment_author_IP, $comment_author_domain ) . "\r\n"; |
---|
1476 | $notify_message .= sprintf( __('URL : %s'), $comment->comment_author_url ) . "\r\n"; |
---|
1477 | $notify_message .= __('Pingback excerpt: ') . "\r\n" . $comment->comment_content . "\r\n\r\n"; |
---|
1478 | break; |
---|
1479 | default: // Comments |
---|
1480 | $notify_message = sprintf( __('A new comment on the post "%s" is waiting for your approval'), $post->post_title ) . "\r\n"; |
---|
1481 | $notify_message .= get_permalink($comment->comment_post_ID) . "\r\n\r\n"; |
---|
1482 | $notify_message .= sprintf( __('Author : %1$s (IP: %2$s , %3$s)'), $comment->comment_author, $comment->comment_author_IP, $comment_author_domain ) . "\r\n"; |
---|
1483 | $notify_message .= sprintf( __('E-mail : %s'), $comment->comment_author_email ) . "\r\n"; |
---|
1484 | $notify_message .= sprintf( __('URL : %s'), $comment->comment_author_url ) . "\r\n"; |
---|
1485 | $notify_message .= sprintf( __('Whois : http://whois.arin.net/rest/ip/%s'), $comment->comment_author_IP ) . "\r\n"; |
---|
1486 | $notify_message .= __('Comment: ') . "\r\n" . $comment->comment_content . "\r\n\r\n"; |
---|
1487 | break; |
---|
1488 | } |
---|
1489 | |
---|
1490 | $notify_message .= sprintf( __('Approve it: %s'), admin_url("comment.php?action=approve&c=$comment_id") ) . "\r\n"; |
---|
1491 | if ( EMPTY_TRASH_DAYS ) |
---|
1492 | $notify_message .= sprintf( __('Trash it: %s'), admin_url("comment.php?action=trash&c=$comment_id") ) . "\r\n"; |
---|
1493 | else |
---|
1494 | $notify_message .= sprintf( __('Delete it: %s'), admin_url("comment.php?action=delete&c=$comment_id") ) . "\r\n"; |
---|
1495 | $notify_message .= sprintf( __('Spam it: %s'), admin_url("comment.php?action=spam&c=$comment_id") ) . "\r\n"; |
---|
1496 | |
---|
1497 | $notify_message .= sprintf( _n('Currently %s comment is waiting for approval. Please visit the moderation panel:', |
---|
1498 | 'Currently %s comments are waiting for approval. Please visit the moderation panel:', $comments_waiting), number_format_i18n($comments_waiting) ) . "\r\n"; |
---|
1499 | $notify_message .= admin_url("edit-comments.php?comment_status=moderated") . "\r\n"; |
---|
1500 | |
---|
1501 | $subject = sprintf( __('[%1$s] Please moderate: "%2$s"'), $blogname, $post->post_title ); |
---|
1502 | $message_headers = ''; |
---|
1503 | |
---|
1504 | /** |
---|
1505 | * Filter the list of recipients for comment moderation emails. |
---|
1506 | * |
---|
1507 | * @since 3.7.0 |
---|
1508 | * |
---|
1509 | * @param array $emails List of email addresses to notify for comment moderation. |
---|
1510 | * @param int $comment_id Comment ID. |
---|
1511 | */ |
---|
1512 | $emails = apply_filters( 'comment_moderation_recipients', $emails, $comment_id ); |
---|
1513 | |
---|
1514 | /** |
---|
1515 | * Filter the comment moderation email text. |
---|
1516 | * |
---|
1517 | * @since 1.5.2 |
---|
1518 | * |
---|
1519 | * @param string $notify_message Text of the comment moderation email. |
---|
1520 | * @param int $comment_id Comment ID. |
---|
1521 | */ |
---|
1522 | $notify_message = apply_filters( 'comment_moderation_text', $notify_message, $comment_id ); |
---|
1523 | |
---|
1524 | /** |
---|
1525 | * Filter the comment moderation email subject. |
---|
1526 | * |
---|
1527 | * @since 1.5.2 |
---|
1528 | * |
---|
1529 | * @param string $subject Subject of the comment moderation email. |
---|
1530 | * @param int $comment_id Comment ID. |
---|
1531 | */ |
---|
1532 | $subject = apply_filters( 'comment_moderation_subject', $subject, $comment_id ); |
---|
1533 | |
---|
1534 | /** |
---|
1535 | * Filter the comment moderation email headers. |
---|
1536 | * |
---|
1537 | * @since 2.8.0 |
---|
1538 | * |
---|
1539 | * @param string $message_headers Headers for the comment moderation email. |
---|
1540 | * @param int $comment_id Comment ID. |
---|
1541 | */ |
---|
1542 | $message_headers = apply_filters( 'comment_moderation_headers', $message_headers, $comment_id ); |
---|
1543 | |
---|
1544 | foreach ( $emails as $email ) { |
---|
1545 | @wp_mail( $email, wp_specialchars_decode( $subject ), $notify_message, $message_headers ); |
---|
1546 | } |
---|
1547 | |
---|
1548 | return true; |
---|
1549 | } |
---|
1550 | endif; |
---|
1551 | |
---|
1552 | if ( !function_exists('wp_password_change_notification') ) : |
---|
1553 | /** |
---|
1554 | * Notify the blog admin of a user changing password, normally via email. |
---|
1555 | * |
---|
1556 | * @since 2.7.0 |
---|
1557 | * |
---|
1558 | * @param object $user User Object |
---|
1559 | */ |
---|
1560 | function wp_password_change_notification(&$user) { |
---|
1561 | // send a copy of password change notification to the admin |
---|
1562 | // but check to see if it's the admin whose password we're changing, and skip this |
---|
1563 | if ( 0 !== strcasecmp( $user->user_email, get_option( 'admin_email' ) ) ) { |
---|
1564 | $message = sprintf(__('Password Lost and Changed for user: %s'), $user->user_login) . "\r\n"; |
---|
1565 | // The blogname option is escaped with esc_html on the way into the database in sanitize_option |
---|
1566 | // we want to reverse this for the plain text arena of emails. |
---|
1567 | $blogname = wp_specialchars_decode(get_option('blogname'), ENT_QUOTES); |
---|
1568 | wp_mail(get_option('admin_email'), sprintf(__('[%s] Password Lost/Changed'), $blogname), $message); |
---|
1569 | } |
---|
1570 | } |
---|
1571 | endif; |
---|
1572 | |
---|
1573 | if ( !function_exists('wp_new_user_notification') ) : |
---|
1574 | /** |
---|
1575 | * Email login credentials to a newly-registered user. |
---|
1576 | * |
---|
1577 | * A new user registration notification is also sent to admin email. |
---|
1578 | * |
---|
1579 | * @since 2.0.0 |
---|
1580 | * |
---|
1581 | * @param int $user_id User ID. |
---|
1582 | * @param string $plaintext_pass Optional. The user's plaintext password. Default empty. |
---|
1583 | */ |
---|
1584 | function wp_new_user_notification($user_id, $plaintext_pass = '') { |
---|
1585 | $user = get_userdata( $user_id ); |
---|
1586 | |
---|
1587 | // The blogname option is escaped with esc_html on the way into the database in sanitize_option |
---|
1588 | // we want to reverse this for the plain text arena of emails. |
---|
1589 | $blogname = wp_specialchars_decode(get_option('blogname'), ENT_QUOTES); |
---|
1590 | |
---|
1591 | $message = sprintf(__('New user registration on your site %s:'), $blogname) . "\r\n\r\n"; |
---|
1592 | $message .= sprintf(__('Username: %s'), $user->user_login) . "\r\n\r\n"; |
---|
1593 | $message .= sprintf(__('E-mail: %s'), $user->user_email) . "\r\n"; |
---|
1594 | |
---|
1595 | @wp_mail(get_option('admin_email'), sprintf(__('[%s] New User Registration'), $blogname), $message); |
---|
1596 | |
---|
1597 | if ( empty($plaintext_pass) ) |
---|
1598 | return; |
---|
1599 | |
---|
1600 | $message = sprintf(__('Username: %s'), $user->user_login) . "\r\n"; |
---|
1601 | $message .= sprintf(__('Password: %s'), $plaintext_pass) . "\r\n"; |
---|
1602 | $message .= wp_login_url() . "\r\n"; |
---|
1603 | |
---|
1604 | wp_mail($user->user_email, sprintf(__('[%s] Your username and password'), $blogname), $message); |
---|
1605 | |
---|
1606 | } |
---|
1607 | endif; |
---|
1608 | |
---|
1609 | if ( !function_exists('wp_nonce_tick') ) : |
---|
1610 | /** |
---|
1611 | * Get the time-dependent variable for nonce creation. |
---|
1612 | * |
---|
1613 | * A nonce has a lifespan of two ticks. Nonces in their second tick may be |
---|
1614 | * updated, e.g. by autosave. |
---|
1615 | * |
---|
1616 | * @since 2.5.0 |
---|
1617 | * |
---|
1618 | * @return int |
---|
1619 | */ |
---|
1620 | function wp_nonce_tick() { |
---|
1621 | /** |
---|
1622 | * Filter the lifespan of nonces in seconds. |
---|
1623 | * |
---|
1624 | * @since 2.5.0 |
---|
1625 | * |
---|
1626 | * @param int $lifespan Lifespan of nonces in seconds. Default 86,400 seconds, or one day. |
---|
1627 | */ |
---|
1628 | $nonce_life = apply_filters( 'nonce_life', DAY_IN_SECONDS ); |
---|
1629 | |
---|
1630 | return ceil(time() / ( $nonce_life / 2 )); |
---|
1631 | } |
---|
1632 | endif; |
---|
1633 | |
---|
1634 | if ( !function_exists('wp_verify_nonce') ) : |
---|
1635 | /** |
---|
1636 | * Verify that correct nonce was used with time limit. |
---|
1637 | * |
---|
1638 | * The user is given an amount of time to use the token, so therefore, since the |
---|
1639 | * UID and $action remain the same, the independent variable is the time. |
---|
1640 | * |
---|
1641 | * @since 2.0.3 |
---|
1642 | * |
---|
1643 | * @param string $nonce Nonce that was used in the form to verify |
---|
1644 | * @param string|int $action Should give context to what is taking place and be the same when nonce was created. |
---|
1645 | * @return bool Whether the nonce check passed or failed. |
---|
1646 | */ |
---|
1647 | function wp_verify_nonce($nonce, $action = -1) { |
---|
1648 | $user = wp_get_current_user(); |
---|
1649 | $uid = (int) $user->ID; |
---|
1650 | if ( ! $uid ) { |
---|
1651 | /** |
---|
1652 | * Filter whether the user who generated the nonce is logged out. |
---|
1653 | * |
---|
1654 | * @since 3.5.0 |
---|
1655 | * |
---|
1656 | * @param int $uid ID of the nonce-owning user. |
---|
1657 | * @param string $action The nonce action. |
---|
1658 | */ |
---|
1659 | $uid = apply_filters( 'nonce_user_logged_out', $uid, $action ); |
---|
1660 | } |
---|
1661 | |
---|
1662 | $i = wp_nonce_tick(); |
---|
1663 | |
---|
1664 | // Nonce generated 0-12 hours ago |
---|
1665 | if ( substr(wp_hash($i . $action . $uid, 'nonce'), -12, 10) === $nonce ) |
---|
1666 | return 1; |
---|
1667 | // Nonce generated 12-24 hours ago |
---|
1668 | if ( substr(wp_hash(($i - 1) . $action . $uid, 'nonce'), -12, 10) === $nonce ) |
---|
1669 | return 2; |
---|
1670 | // Invalid nonce |
---|
1671 | return false; |
---|
1672 | } |
---|
1673 | endif; |
---|
1674 | |
---|
1675 | if ( !function_exists('wp_create_nonce') ) : |
---|
1676 | /** |
---|
1677 | * Creates a random, one time use token. |
---|
1678 | * |
---|
1679 | * @since 2.0.3 |
---|
1680 | * |
---|
1681 | * @param string|int $action Scalar value to add context to the nonce. |
---|
1682 | * @return string The one use form token |
---|
1683 | */ |
---|
1684 | function wp_create_nonce($action = -1) { |
---|
1685 | $user = wp_get_current_user(); |
---|
1686 | $uid = (int) $user->ID; |
---|
1687 | if ( ! $uid ) { |
---|
1688 | /** This filter is documented in wp-includes/pluggable.php */ |
---|
1689 | $uid = apply_filters( 'nonce_user_logged_out', $uid, $action ); |
---|
1690 | } |
---|
1691 | |
---|
1692 | $i = wp_nonce_tick(); |
---|
1693 | |
---|
1694 | return substr(wp_hash($i . $action . $uid, 'nonce'), -12, 10); |
---|
1695 | } |
---|
1696 | endif; |
---|
1697 | |
---|
1698 | if ( !function_exists('wp_salt') ) : |
---|
1699 | /** |
---|
1700 | * Get salt to add to hashes. |
---|
1701 | * |
---|
1702 | * Salts are created using secret keys. Secret keys are located in two places: |
---|
1703 | * in the database and in the wp-config.php file. The secret key in the database |
---|
1704 | * is randomly generated and will be appended to the secret keys in wp-config.php. |
---|
1705 | * |
---|
1706 | * The secret keys in wp-config.php should be updated to strong, random keys to maximize |
---|
1707 | * security. Below is an example of how the secret key constants are defined. |
---|
1708 | * Do not paste this example directly into wp-config.php. Instead, have a |
---|
1709 | * {@link https://api.wordpress.org/secret-key/1.1/salt/ secret key created} just |
---|
1710 | * for you. |
---|
1711 | * |
---|
1712 | * <code> |
---|
1713 | * define('AUTH_KEY', ' Xakm<o xQy rw4EMsLKM-?!T+,PFF})H4lzcW57AF0U@N@< >M%G4Yt>f`z]MON'); |
---|
1714 | * define('SECURE_AUTH_KEY', 'LzJ}op]mr|6+![P}Ak:uNdJCJZd>(Hx.-Mh#Tz)pCIU#uGEnfFz|f ;;eU%/U^O~'); |
---|
1715 | * define('LOGGED_IN_KEY', '|i|Ux`9<p-h$aFf(qnT:sDO:D1P^wZ$$/Ra@miTJi9G;ddp_<q}6H1)o|a +&JCM'); |
---|
1716 | * define('NONCE_KEY', '%:R{[P|,s.KuMltH5}cI;/k<Gx~j!f0I)m_sIyu+&NJZ)-iO>z7X>QYR0Z_XnZ@|'); |
---|
1717 | * define('AUTH_SALT', 'eZyT)-Naw]F8CwA*VaW#q*|.)g@o}||wf~@C-YSt}(dh_r6EbI#A,y|nU2{B#JBW'); |
---|
1718 | * define('SECURE_AUTH_SALT', '!=oLUTXh,QW=H `}`L|9/^4-3 STz},T(w}W<I`.JjPi)<Bmf1v,HpGe}T1:Xt7n'); |
---|
1719 | * define('LOGGED_IN_SALT', '+XSqHc;@Q*K_b|Z?NC[3H!!EONbh.n<+=uKR:>*c(u`g~EJBf#8u#R{mUEZrozmm'); |
---|
1720 | * define('NONCE_SALT', 'h`GXHhD>SLWVfg1(1(N{;.V!MoE(SfbA_ksP@&`+AycHcAV$+?@3q+rxV{%^VyKT'); |
---|
1721 | * </code> |
---|
1722 | * |
---|
1723 | * Salting passwords helps against tools which has stored hashed values of |
---|
1724 | * common dictionary strings. The added values makes it harder to crack. |
---|
1725 | * |
---|
1726 | * @since 2.5.0 |
---|
1727 | * |
---|
1728 | * @link https://api.wordpress.org/secret-key/1.1/salt/ Create secrets for wp-config.php |
---|
1729 | * |
---|
1730 | * @param string $scheme Authentication scheme (auth, secure_auth, logged_in, nonce) |
---|
1731 | * @return string Salt value |
---|
1732 | */ |
---|
1733 | function wp_salt( $scheme = 'auth' ) { |
---|
1734 | static $cached_salts = array(); |
---|
1735 | if ( isset( $cached_salts[ $scheme ] ) ) { |
---|
1736 | /** |
---|
1737 | * Filter the WordPress salt. |
---|
1738 | * |
---|
1739 | * @since 2.5.0 |
---|
1740 | * |
---|
1741 | * @param string $cached_salt Cached salt for the given scheme. |
---|
1742 | * @param string $scheme Authentication scheme. Values include 'auth', |
---|
1743 | * 'secure_auth', 'logged_in', and 'nonce'. |
---|
1744 | */ |
---|
1745 | return apply_filters( 'salt', $cached_salts[ $scheme ], $scheme ); |
---|
1746 | } |
---|
1747 | |
---|
1748 | static $duplicated_keys; |
---|
1749 | if ( null === $duplicated_keys ) { |
---|
1750 | $duplicated_keys = array( 'put your unique phrase here' => true ); |
---|
1751 | foreach ( array( 'AUTH', 'SECURE_AUTH', 'LOGGED_IN', 'NONCE', 'SECRET' ) as $first ) { |
---|
1752 | foreach ( array( 'KEY', 'SALT' ) as $second ) { |
---|
1753 | if ( ! defined( "{$first}_{$second}" ) ) |
---|
1754 | continue; |
---|
1755 | $value = constant( "{$first}_{$second}" ); |
---|
1756 | $duplicated_keys[ $value ] = isset( $duplicated_keys[ $value ] ); |
---|
1757 | } |
---|
1758 | } |
---|
1759 | } |
---|
1760 | |
---|
1761 | $key = $salt = ''; |
---|
1762 | if ( defined( 'SECRET_KEY' ) && SECRET_KEY && empty( $duplicated_keys[ SECRET_KEY ] ) ) |
---|
1763 | $key = SECRET_KEY; |
---|
1764 | if ( 'auth' == $scheme && defined( 'SECRET_SALT' ) && SECRET_SALT && empty( $duplicated_keys[ SECRET_SALT ] ) ) |
---|
1765 | $salt = SECRET_SALT; |
---|
1766 | |
---|
1767 | if ( in_array( $scheme, array( 'auth', 'secure_auth', 'logged_in', 'nonce' ) ) ) { |
---|
1768 | foreach ( array( 'key', 'salt' ) as $type ) { |
---|
1769 | $const = strtoupper( "{$scheme}_{$type}" ); |
---|
1770 | if ( defined( $const ) && constant( $const ) && empty( $duplicated_keys[ constant( $const ) ] ) ) { |
---|
1771 | $$type = constant( $const ); |
---|
1772 | } elseif ( ! $$type ) { |
---|
1773 | $$type = get_site_option( "{$scheme}_{$type}" ); |
---|
1774 | if ( ! $$type ) { |
---|
1775 | $$type = wp_generate_password( 64, true, true ); |
---|
1776 | update_site_option( "{$scheme}_{$type}", $$type ); |
---|
1777 | } |
---|
1778 | } |
---|
1779 | } |
---|
1780 | } else { |
---|
1781 | if ( ! $key ) { |
---|
1782 | $key = get_site_option( 'secret_key' ); |
---|
1783 | if ( ! $key ) { |
---|
1784 | $key = wp_generate_password( 64, true, true ); |
---|
1785 | update_site_option( 'secret_key', $key ); |
---|
1786 | } |
---|
1787 | } |
---|
1788 | $salt = hash_hmac( 'md5', $scheme, $key ); |
---|
1789 | } |
---|
1790 | |
---|
1791 | $cached_salts[ $scheme ] = $key . $salt; |
---|
1792 | |
---|
1793 | /** This filter is documented in wp-includes/pluggable.php */ |
---|
1794 | return apply_filters( 'salt', $cached_salts[ $scheme ], $scheme ); |
---|
1795 | } |
---|
1796 | endif; |
---|
1797 | |
---|
1798 | if ( !function_exists('wp_hash') ) : |
---|
1799 | /** |
---|
1800 | * Get hash of given string. |
---|
1801 | * |
---|
1802 | * @since 2.0.3 |
---|
1803 | * @uses wp_salt() Get WordPress salt |
---|
1804 | * |
---|
1805 | * @param string $data Plain text to hash |
---|
1806 | * @return string Hash of $data |
---|
1807 | */ |
---|
1808 | function wp_hash($data, $scheme = 'auth') { |
---|
1809 | $salt = wp_salt($scheme); |
---|
1810 | |
---|
1811 | return hash_hmac('md5', $data, $salt); |
---|
1812 | } |
---|
1813 | endif; |
---|
1814 | |
---|
1815 | if ( !function_exists('wp_hash_password') ) : |
---|
1816 | /** |
---|
1817 | * Create a hash (encrypt) of a plain text password. |
---|
1818 | * |
---|
1819 | * For integration with other applications, this function can be overwritten to |
---|
1820 | * instead use the other package password checking algorithm. |
---|
1821 | * |
---|
1822 | * @since 2.5.0 |
---|
1823 | * |
---|
1824 | * @global object $wp_hasher PHPass object |
---|
1825 | * @uses PasswordHash::HashPassword |
---|
1826 | * |
---|
1827 | * @param string $password Plain text user password to hash |
---|
1828 | * @return string The hash string of the password |
---|
1829 | */ |
---|
1830 | function wp_hash_password($password) { |
---|
1831 | global $wp_hasher; |
---|
1832 | |
---|
1833 | if ( empty($wp_hasher) ) { |
---|
1834 | require_once( ABSPATH . 'wp-includes/class-phpass.php'); |
---|
1835 | // By default, use the portable hash from phpass |
---|
1836 | $wp_hasher = new PasswordHash(8, true); |
---|
1837 | } |
---|
1838 | |
---|
1839 | return $wp_hasher->HashPassword( trim( $password ) ); |
---|
1840 | } |
---|
1841 | endif; |
---|
1842 | |
---|
1843 | if ( !function_exists('wp_check_password') ) : |
---|
1844 | /** |
---|
1845 | * Checks the plaintext password against the encrypted Password. |
---|
1846 | * |
---|
1847 | * Maintains compatibility between old version and the new cookie authentication |
---|
1848 | * protocol using PHPass library. The $hash parameter is the encrypted password |
---|
1849 | * and the function compares the plain text password when encrypted similarly |
---|
1850 | * against the already encrypted password to see if they match. |
---|
1851 | * |
---|
1852 | * For integration with other applications, this function can be overwritten to |
---|
1853 | * instead use the other package password checking algorithm. |
---|
1854 | * |
---|
1855 | * @since 2.5.0 |
---|
1856 | * |
---|
1857 | * @global object $wp_hasher PHPass object used for checking the password |
---|
1858 | * against the $hash + $password |
---|
1859 | * @uses PasswordHash::CheckPassword |
---|
1860 | * |
---|
1861 | * @param string $password Plaintext user's password |
---|
1862 | * @param string $hash Hash of the user's password to check against. |
---|
1863 | * @return bool False, if the $password does not match the hashed password |
---|
1864 | */ |
---|
1865 | function wp_check_password($password, $hash, $user_id = '') { |
---|
1866 | global $wp_hasher; |
---|
1867 | |
---|
1868 | // If the hash is still md5... |
---|
1869 | if ( strlen($hash) <= 32 ) { |
---|
1870 | $check = ( $hash == md5($password) ); |
---|
1871 | if ( $check && $user_id ) { |
---|
1872 | // Rehash using new hash. |
---|
1873 | wp_set_password($password, $user_id); |
---|
1874 | $hash = wp_hash_password($password); |
---|
1875 | } |
---|
1876 | |
---|
1877 | /** |
---|
1878 | * Filter whether the plaintext password matches the encrypted password. |
---|
1879 | * |
---|
1880 | * @since 2.5.0 |
---|
1881 | * |
---|
1882 | * @param bool $check Whether the passwords match. |
---|
1883 | * @param string $hash The hashed password. |
---|
1884 | * @param int $user_id User ID. |
---|
1885 | */ |
---|
1886 | return apply_filters( 'check_password', $check, $password, $hash, $user_id ); |
---|
1887 | } |
---|
1888 | |
---|
1889 | // If the stored hash is longer than an MD5, presume the |
---|
1890 | // new style phpass portable hash. |
---|
1891 | if ( empty($wp_hasher) ) { |
---|
1892 | require_once( ABSPATH . 'wp-includes/class-phpass.php'); |
---|
1893 | // By default, use the portable hash from phpass |
---|
1894 | $wp_hasher = new PasswordHash(8, true); |
---|
1895 | } |
---|
1896 | |
---|
1897 | $check = $wp_hasher->CheckPassword($password, $hash); |
---|
1898 | |
---|
1899 | /** This filter is documented in wp-includes/pluggable.php */ |
---|
1900 | return apply_filters( 'check_password', $check, $password, $hash, $user_id ); |
---|
1901 | } |
---|
1902 | endif; |
---|
1903 | |
---|
1904 | if ( !function_exists('wp_generate_password') ) : |
---|
1905 | /** |
---|
1906 | * Generates a random password drawn from the defined set of characters. |
---|
1907 | * |
---|
1908 | * @since 2.5.0 |
---|
1909 | * |
---|
1910 | * @param int $length The length of password to generate |
---|
1911 | * @param bool $special_chars Whether to include standard special characters. Default true. |
---|
1912 | * @param bool $extra_special_chars Whether to include other special characters. Used when |
---|
1913 | * generating secret keys and salts. Default false. |
---|
1914 | * @return string The random password |
---|
1915 | **/ |
---|
1916 | function wp_generate_password( $length = 12, $special_chars = true, $extra_special_chars = false ) { |
---|
1917 | $chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'; |
---|
1918 | if ( $special_chars ) |
---|
1919 | $chars .= '!@#$%^&*()'; |
---|
1920 | if ( $extra_special_chars ) |
---|
1921 | $chars .= '-_ []{}<>~`+=,.;:/?|'; |
---|
1922 | |
---|
1923 | $password = ''; |
---|
1924 | for ( $i = 0; $i < $length; $i++ ) { |
---|
1925 | $password .= substr($chars, wp_rand(0, strlen($chars) - 1), 1); |
---|
1926 | } |
---|
1927 | |
---|
1928 | /** |
---|
1929 | * Filter the randomly-generated password. |
---|
1930 | * |
---|
1931 | * @since 3.0.0 |
---|
1932 | * |
---|
1933 | * @param string $password The generated password. |
---|
1934 | */ |
---|
1935 | return apply_filters( 'random_password', $password ); |
---|
1936 | } |
---|
1937 | endif; |
---|
1938 | |
---|
1939 | if ( !function_exists('wp_rand') ) : |
---|
1940 | /** |
---|
1941 | * Generates a random number |
---|
1942 | * |
---|
1943 | * @since 2.6.2 |
---|
1944 | * |
---|
1945 | * @param int $min Lower limit for the generated number |
---|
1946 | * @param int $max Upper limit for the generated number |
---|
1947 | * @return int A random number between min and max |
---|
1948 | */ |
---|
1949 | function wp_rand( $min = 0, $max = 0 ) { |
---|
1950 | global $rnd_value; |
---|
1951 | |
---|
1952 | // Reset $rnd_value after 14 uses |
---|
1953 | // 32(md5) + 40(sha1) + 40(sha1) / 8 = 14 random numbers from $rnd_value |
---|
1954 | if ( strlen($rnd_value) < 8 ) { |
---|
1955 | if ( defined( 'WP_SETUP_CONFIG' ) ) |
---|
1956 | static $seed = ''; |
---|
1957 | else |
---|
1958 | $seed = get_transient('random_seed'); |
---|
1959 | $rnd_value = md5( uniqid(microtime() . mt_rand(), true ) . $seed ); |
---|
1960 | $rnd_value .= sha1($rnd_value); |
---|
1961 | $rnd_value .= sha1($rnd_value . $seed); |
---|
1962 | $seed = md5($seed . $rnd_value); |
---|
1963 | if ( ! defined( 'WP_SETUP_CONFIG' ) ) |
---|
1964 | set_transient('random_seed', $seed); |
---|
1965 | } |
---|
1966 | |
---|
1967 | // Take the first 8 digits for our value |
---|
1968 | $value = substr($rnd_value, 0, 8); |
---|
1969 | |
---|
1970 | // Strip the first eight, leaving the remainder for the next call to wp_rand(). |
---|
1971 | $rnd_value = substr($rnd_value, 8); |
---|
1972 | |
---|
1973 | $value = abs(hexdec($value)); |
---|
1974 | |
---|
1975 | // Some misconfigured 32bit environments (Entropy PHP, for example) truncate integers larger than PHP_INT_MAX to PHP_INT_MAX rather than overflowing them to floats. |
---|
1976 | $max_random_number = 3000000000 === 2147483647 ? (float) "4294967295" : 4294967295; // 4294967295 = 0xffffffff |
---|
1977 | |
---|
1978 | // Reduce the value to be within the min - max range |
---|
1979 | if ( $max != 0 ) |
---|
1980 | $value = $min + ( $max - $min + 1 ) * $value / ( $max_random_number + 1 ); |
---|
1981 | |
---|
1982 | return abs(intval($value)); |
---|
1983 | } |
---|
1984 | endif; |
---|
1985 | |
---|
1986 | if ( !function_exists('wp_set_password') ) : |
---|
1987 | /** |
---|
1988 | * Updates the user's password with a new encrypted one. |
---|
1989 | * |
---|
1990 | * For integration with other applications, this function can be overwritten to |
---|
1991 | * instead use the other package password checking algorithm. |
---|
1992 | * |
---|
1993 | * @since 2.5.0 |
---|
1994 | * |
---|
1995 | * @uses $wpdb WordPress database object for queries |
---|
1996 | * @uses wp_hash_password() Used to encrypt the user's password before passing to the database |
---|
1997 | * |
---|
1998 | * @param string $password The plaintext new user password |
---|
1999 | * @param int $user_id User ID |
---|
2000 | */ |
---|
2001 | function wp_set_password( $password, $user_id ) { |
---|
2002 | global $wpdb; |
---|
2003 | |
---|
2004 | $hash = wp_hash_password( $password ); |
---|
2005 | $wpdb->update($wpdb->users, array('user_pass' => $hash, 'user_activation_key' => ''), array('ID' => $user_id) ); |
---|
2006 | |
---|
2007 | wp_cache_delete($user_id, 'users'); |
---|
2008 | } |
---|
2009 | endif; |
---|
2010 | |
---|
2011 | if ( !function_exists( 'get_avatar' ) ) : |
---|
2012 | /** |
---|
2013 | * Retrieve the avatar for a user who provided a user ID or email address. |
---|
2014 | * |
---|
2015 | * @since 2.5.0 |
---|
2016 | * |
---|
2017 | * @param int|string|object $id_or_email A user ID, email address, or comment object |
---|
2018 | * @param int $size Size of the avatar image |
---|
2019 | * @param string $default URL to a default image to use if no avatar is available |
---|
2020 | * @param string $alt Alternative text to use in image tag. Defaults to blank |
---|
2021 | * @return string <img> tag for the user's avatar |
---|
2022 | */ |
---|
2023 | function get_avatar( $id_or_email, $size = '96', $default = '', $alt = false ) { |
---|
2024 | if ( ! get_option('show_avatars') ) |
---|
2025 | return false; |
---|
2026 | |
---|
2027 | if ( false === $alt) |
---|
2028 | $safe_alt = ''; |
---|
2029 | else |
---|
2030 | $safe_alt = esc_attr( $alt ); |
---|
2031 | |
---|
2032 | if ( !is_numeric($size) ) |
---|
2033 | $size = '96'; |
---|
2034 | |
---|
2035 | $email = ''; |
---|
2036 | if ( is_numeric($id_or_email) ) { |
---|
2037 | $id = (int) $id_or_email; |
---|
2038 | $user = get_userdata($id); |
---|
2039 | if ( $user ) |
---|
2040 | $email = $user->user_email; |
---|
2041 | } elseif ( is_object($id_or_email) ) { |
---|
2042 | // No avatar for pingbacks or trackbacks |
---|
2043 | |
---|
2044 | /** |
---|
2045 | * Filter the list of allowed comment types for retrieving avatars. |
---|
2046 | * |
---|
2047 | * @since 3.0.0 |
---|
2048 | * |
---|
2049 | * @param array $types An array of content types. Default only contains 'comment'. |
---|
2050 | */ |
---|
2051 | $allowed_comment_types = apply_filters( 'get_avatar_comment_types', array( 'comment' ) ); |
---|
2052 | if ( ! empty( $id_or_email->comment_type ) && ! in_array( $id_or_email->comment_type, (array) $allowed_comment_types ) ) |
---|
2053 | return false; |
---|
2054 | |
---|
2055 | if ( ! empty( $id_or_email->user_id ) ) { |
---|
2056 | $id = (int) $id_or_email->user_id; |
---|
2057 | $user = get_userdata($id); |
---|
2058 | if ( $user ) |
---|
2059 | $email = $user->user_email; |
---|
2060 | } |
---|
2061 | |
---|
2062 | if ( ! $email && ! empty( $id_or_email->comment_author_email ) ) |
---|
2063 | $email = $id_or_email->comment_author_email; |
---|
2064 | } else { |
---|
2065 | $email = $id_or_email; |
---|
2066 | } |
---|
2067 | |
---|
2068 | if ( empty($default) ) { |
---|
2069 | $avatar_default = get_option('avatar_default'); |
---|
2070 | if ( empty($avatar_default) ) |
---|
2071 | $default = 'mystery'; |
---|
2072 | else |
---|
2073 | $default = $avatar_default; |
---|
2074 | } |
---|
2075 | |
---|
2076 | if ( !empty($email) ) |
---|
2077 | $email_hash = md5( strtolower( trim( $email ) ) ); |
---|
2078 | |
---|
2079 | if ( is_ssl() ) { |
---|
2080 | $host = 'https://secure.gravatar.com'; |
---|
2081 | } else { |
---|
2082 | if ( !empty($email) ) |
---|
2083 | $host = sprintf( "http://%d.gravatar.com", ( hexdec( $email_hash[0] ) % 2 ) ); |
---|
2084 | else |
---|
2085 | $host = 'http://0.gravatar.com'; |
---|
2086 | } |
---|
2087 | |
---|
2088 | if ( 'mystery' == $default ) |
---|
2089 | $default = "$host/avatar/ad516503a11cd5ca435acc9bb6523536?s={$size}"; // ad516503a11cd5ca435acc9bb6523536 == md5('unknown@gravatar.com') |
---|
2090 | elseif ( 'blank' == $default ) |
---|
2091 | $default = $email ? 'blank' : includes_url( 'images/blank.gif' ); |
---|
2092 | elseif ( !empty($email) && 'gravatar_default' == $default ) |
---|
2093 | $default = ''; |
---|
2094 | elseif ( 'gravatar_default' == $default ) |
---|
2095 | $default = "$host/avatar/?s={$size}"; |
---|
2096 | elseif ( empty($email) ) |
---|
2097 | $default = "$host/avatar/?d=$default&s={$size}"; |
---|
2098 | elseif ( strpos($default, 'http://') === 0 ) |
---|
2099 | $default = add_query_arg( 's', $size, $default ); |
---|
2100 | |
---|
2101 | if ( !empty($email) ) { |
---|
2102 | $out = "$host/avatar/"; |
---|
2103 | $out .= $email_hash; |
---|
2104 | $out .= '?s='.$size; |
---|
2105 | $out .= '&d=' . urlencode( $default ); |
---|
2106 | |
---|
2107 | $rating = get_option('avatar_rating'); |
---|
2108 | if ( !empty( $rating ) ) |
---|
2109 | $out .= "&r={$rating}"; |
---|
2110 | |
---|
2111 | $out = str_replace( '&', '&', esc_url( $out ) ); |
---|
2112 | $avatar = "<img alt='{$safe_alt}' src='{$out}' class='avatar avatar-{$size} photo' height='{$size}' width='{$size}' />"; |
---|
2113 | } else { |
---|
2114 | $avatar = "<img alt='{$safe_alt}' src='{$default}' class='avatar avatar-{$size} photo avatar-default' height='{$size}' width='{$size}' />"; |
---|
2115 | } |
---|
2116 | |
---|
2117 | /** |
---|
2118 | * Filter the avatar to retrieve. |
---|
2119 | * |
---|
2120 | * @since 2.5.0 |
---|
2121 | * |
---|
2122 | * @param string $avatar Image tag for the user's avatar. |
---|
2123 | * @param int|object|string $id_or_email A user ID, email address, or comment object. |
---|
2124 | * @param int $size Square avatar width and height in pixels to retrieve. |
---|
2125 | * @param string $alt Alternative text to use in the avatar image tag. |
---|
2126 | * Default empty. |
---|
2127 | */ |
---|
2128 | return apply_filters( 'get_avatar', $avatar, $id_or_email, $size, $default, $alt ); |
---|
2129 | } |
---|
2130 | endif; |
---|
2131 | |
---|
2132 | if ( !function_exists( 'wp_text_diff' ) ) : |
---|
2133 | /** |
---|
2134 | * Displays a human readable HTML representation of the difference between two strings. |
---|
2135 | * |
---|
2136 | * The Diff is available for getting the changes between versions. The output is |
---|
2137 | * HTML, so the primary use is for displaying the changes. If the two strings |
---|
2138 | * are equivalent, then an empty string will be returned. |
---|
2139 | * |
---|
2140 | * The arguments supported and can be changed are listed below. |
---|
2141 | * |
---|
2142 | * 'title' : Default is an empty string. Titles the diff in a manner compatible |
---|
2143 | * with the output. |
---|
2144 | * 'title_left' : Default is an empty string. Change the HTML to the left of the |
---|
2145 | * title. |
---|
2146 | * 'title_right' : Default is an empty string. Change the HTML to the right of |
---|
2147 | * the title. |
---|
2148 | * |
---|
2149 | * @since 2.6.0 |
---|
2150 | * |
---|
2151 | * @see wp_parse_args() Used to change defaults to user defined settings. |
---|
2152 | * @uses Text_Diff |
---|
2153 | * @uses WP_Text_Diff_Renderer_Table |
---|
2154 | * |
---|
2155 | * @param string $left_string "old" (left) version of string |
---|
2156 | * @param string $right_string "new" (right) version of string |
---|
2157 | * @param string|array $args Optional. Change 'title', 'title_left', and 'title_right' defaults. |
---|
2158 | * @return string Empty string if strings are equivalent or HTML with differences. |
---|
2159 | */ |
---|
2160 | function wp_text_diff( $left_string, $right_string, $args = null ) { |
---|
2161 | $defaults = array( 'title' => '', 'title_left' => '', 'title_right' => '' ); |
---|
2162 | $args = wp_parse_args( $args, $defaults ); |
---|
2163 | |
---|
2164 | if ( !class_exists( 'WP_Text_Diff_Renderer_Table' ) ) |
---|
2165 | require( ABSPATH . WPINC . '/wp-diff.php' ); |
---|
2166 | |
---|
2167 | $left_string = normalize_whitespace($left_string); |
---|
2168 | $right_string = normalize_whitespace($right_string); |
---|
2169 | |
---|
2170 | $left_lines = explode("\n", $left_string); |
---|
2171 | $right_lines = explode("\n", $right_string); |
---|
2172 | $text_diff = new Text_Diff($left_lines, $right_lines); |
---|
2173 | $renderer = new WP_Text_Diff_Renderer_Table( $args ); |
---|
2174 | $diff = $renderer->render($text_diff); |
---|
2175 | |
---|
2176 | if ( !$diff ) |
---|
2177 | return ''; |
---|
2178 | |
---|
2179 | $r = "<table class='diff'>\n"; |
---|
2180 | |
---|
2181 | if ( ! empty( $args[ 'show_split_view' ] ) ) { |
---|
2182 | $r .= "<col class='content diffsplit left' /><col class='content diffsplit middle' /><col class='content diffsplit right' />"; |
---|
2183 | } else { |
---|
2184 | $r .= "<col class='content' />"; |
---|
2185 | } |
---|
2186 | |
---|
2187 | if ( $args['title'] || $args['title_left'] || $args['title_right'] ) |
---|
2188 | $r .= "<thead>"; |
---|
2189 | if ( $args['title'] ) |
---|
2190 | $r .= "<tr class='diff-title'><th colspan='4'>$args[title]</th></tr>\n"; |
---|
2191 | if ( $args['title_left'] || $args['title_right'] ) { |
---|
2192 | $r .= "<tr class='diff-sub-title'>\n"; |
---|
2193 | $r .= "\t<td></td><th>$args[title_left]</th>\n"; |
---|
2194 | $r .= "\t<td></td><th>$args[title_right]</th>\n"; |
---|
2195 | $r .= "</tr>\n"; |
---|
2196 | } |
---|
2197 | if ( $args['title'] || $args['title_left'] || $args['title_right'] ) |
---|
2198 | $r .= "</thead>\n"; |
---|
2199 | |
---|
2200 | $r .= "<tbody>\n$diff\n</tbody>\n"; |
---|
2201 | $r .= "</table>"; |
---|
2202 | |
---|
2203 | return $r; |
---|
2204 | } |
---|
2205 | endif; |
---|
2206 | |
---|