wp/wp-mail.php
changeset 9 177826044cd9
parent 7 cf61fcea0001
child 16 a86126ab1dd4
equal deleted inserted replaced
8:c7c34916027a 9:177826044cd9
     6  *
     6  *
     7  * @package WordPress
     7  * @package WordPress
     8  */
     8  */
     9 
     9 
    10 /** Make sure that the WordPress bootstrap has run before continuing. */
    10 /** Make sure that the WordPress bootstrap has run before continuing. */
    11 require(dirname(__FILE__) . '/wp-load.php');
    11 require( dirname( __FILE__ ) . '/wp-load.php' );
    12 
    12 
    13 /** This filter is documented in wp-admin/options.php */
    13 /** This filter is documented in wp-admin/options.php */
    14 if ( ! apply_filters( 'enable_post_by_email_configuration', true ) )
    14 if ( ! apply_filters( 'enable_post_by_email_configuration', true ) ) {
    15 	wp_die( __( 'This action has been disabled by the administrator.' ), 403 );
    15 	wp_die( __( 'This action has been disabled by the administrator.' ), 403 );
       
    16 }
    16 
    17 
    17 $mailserver_url = get_option( 'mailserver_url' );
    18 $mailserver_url = get_option( 'mailserver_url' );
    18 
    19 
    19 if ( 'mail.example.com' === $mailserver_url || empty( $mailserver_url ) ) {
    20 if ( 'mail.example.com' === $mailserver_url || empty( $mailserver_url ) ) {
    20 	wp_die( __( 'This action has been disabled by the administrator.' ), 403 );
    21 	wp_die( __( 'This action has been disabled by the administrator.' ), 403 );
    29 
    30 
    30 /** Get the POP3 class with which to access the mailbox. */
    31 /** Get the POP3 class with which to access the mailbox. */
    31 require_once( ABSPATH . WPINC . '/class-pop3.php' );
    32 require_once( ABSPATH . WPINC . '/class-pop3.php' );
    32 
    33 
    33 /** Only check at this interval for new messages. */
    34 /** Only check at this interval for new messages. */
    34 if ( !defined('WP_MAIL_INTERVAL') )
    35 if ( ! defined( 'WP_MAIL_INTERVAL' ) ) {
    35 	define('WP_MAIL_INTERVAL', 300); // 5 minutes
    36 	define( 'WP_MAIL_INTERVAL', 300 ); // 5 minutes
    36 
    37 }
    37 $last_checked = get_transient('mailserver_last_checked');
    38 
    38 
    39 $last_checked = get_transient( 'mailserver_last_checked' );
    39 if ( $last_checked )
    40 
    40 	wp_die(__('Slow down cowboy, no need to check for new mails so often!'));
    41 if ( $last_checked ) {
    41 
    42 	wp_die( __( 'Slow down cowboy, no need to check for new mails so often!' ) );
    42 set_transient('mailserver_last_checked', true, WP_MAIL_INTERVAL);
    43 }
    43 
    44 
    44 $time_difference = get_option('gmt_offset') * HOUR_IN_SECONDS;
    45 set_transient( 'mailserver_last_checked', true, WP_MAIL_INTERVAL );
       
    46 
       
    47 $time_difference = get_option( 'gmt_offset' ) * HOUR_IN_SECONDS;
    45 
    48 
    46 $phone_delim = '::';
    49 $phone_delim = '::';
    47 
    50 
    48 $pop3 = new POP3();
    51 $pop3 = new POP3();
    49 
    52 
    50 if ( !$pop3->connect( get_option('mailserver_url'), get_option('mailserver_port') ) || !$pop3->user( get_option('mailserver_login') ) )
    53 if ( ! $pop3->connect( get_option( 'mailserver_url' ), get_option( 'mailserver_port' ) ) || ! $pop3->user( get_option( 'mailserver_login' ) ) ) {
    51 	wp_die( esc_html( $pop3->ERROR ) );
    54 	wp_die( esc_html( $pop3->ERROR ) );
    52 
    55 }
    53 $count = $pop3->pass( get_option('mailserver_pass') );
    56 
    54 
    57 $count = $pop3->pass( get_option( 'mailserver_pass' ) );
    55 if( false === $count )
    58 
       
    59 if ( false === $count ) {
    56 	wp_die( esc_html( $pop3->ERROR ) );
    60 	wp_die( esc_html( $pop3->ERROR ) );
    57 
    61 }
    58 if( 0 === $count ) {
    62 
       
    63 if ( 0 === $count ) {
    59 	$pop3->quit();
    64 	$pop3->quit();
    60 	wp_die( __('There doesn’t seem to be any new mail.') );
    65 	wp_die( __( 'There doesn’t seem to be any new mail.' ) );
    61 }
    66 }
    62 
    67 
    63 for ( $i = 1; $i <= $count; $i++ ) {
    68 for ( $i = 1; $i <= $count; $i++ ) {
    64 
    69 
    65 	$message = $pop3->get($i);
    70 	$message = $pop3->get( $i );
    66 
    71 
    67 	$bodysignal = false;
    72 	$bodysignal                = false;
    68 	$boundary = '';
    73 	$boundary                  = '';
    69 	$charset = '';
    74 	$charset                   = '';
    70 	$content = '';
    75 	$content                   = '';
    71 	$content_type = '';
    76 	$content_type              = '';
    72 	$content_transfer_encoding = '';
    77 	$content_transfer_encoding = '';
    73 	$post_author = 1;
    78 	$post_author               = 1;
    74 	$author_found = false;
    79 	$author_found              = false;
    75 	foreach ($message as $line) {
    80 	foreach ( $message as $line ) {
    76 		// Body signal.
    81 		// Body signal.
    77 		if ( strlen($line) < 3 )
    82 		if ( strlen( $line ) < 3 ) {
    78 			$bodysignal = true;
    83 			$bodysignal = true;
       
    84 		}
    79 		if ( $bodysignal ) {
    85 		if ( $bodysignal ) {
    80 			$content .= $line;
    86 			$content .= $line;
    81 		} else {
    87 		} else {
    82 			if ( preg_match('/Content-Type: /i', $line) ) {
    88 			if ( preg_match( '/Content-Type: /i', $line ) ) {
    83 				$content_type = trim($line);
    89 				$content_type = trim( $line );
    84 				$content_type = substr($content_type, 14, strlen($content_type) - 14);
    90 				$content_type = substr( $content_type, 14, strlen( $content_type ) - 14 );
    85 				$content_type = explode(';', $content_type);
    91 				$content_type = explode( ';', $content_type );
    86 				if ( ! empty( $content_type[1] ) ) {
    92 				if ( ! empty( $content_type[1] ) ) {
    87 					$charset = explode('=', $content_type[1]);
    93 					$charset = explode( '=', $content_type[1] );
    88 					$charset = ( ! empty( $charset[1] ) ) ? trim($charset[1]) : '';
    94 					$charset = ( ! empty( $charset[1] ) ) ? trim( $charset[1] ) : '';
    89 				}
    95 				}
    90 				$content_type = $content_type[0];
    96 				$content_type = $content_type[0];
    91 			}
    97 			}
    92 			if ( preg_match('/Content-Transfer-Encoding: /i', $line) ) {
    98 			if ( preg_match( '/Content-Transfer-Encoding: /i', $line ) ) {
    93 				$content_transfer_encoding = trim($line);
    99 				$content_transfer_encoding = trim( $line );
    94 				$content_transfer_encoding = substr($content_transfer_encoding, 27, strlen($content_transfer_encoding) - 27);
   100 				$content_transfer_encoding = substr( $content_transfer_encoding, 27, strlen( $content_transfer_encoding ) - 27 );
    95 				$content_transfer_encoding = explode(';', $content_transfer_encoding);
   101 				$content_transfer_encoding = explode( ';', $content_transfer_encoding );
    96 				$content_transfer_encoding = $content_transfer_encoding[0];
   102 				$content_transfer_encoding = $content_transfer_encoding[0];
    97 			}
   103 			}
    98 			if ( ( $content_type == 'multipart/alternative' ) && ( false !== strpos($line, 'boundary="') ) && ( '' == $boundary ) ) {
   104 			if ( ( $content_type == 'multipart/alternative' ) && ( false !== strpos( $line, 'boundary="' ) ) && ( '' == $boundary ) ) {
    99 				$boundary = trim($line);
   105 				$boundary = trim( $line );
   100 				$boundary = explode('"', $boundary);
   106 				$boundary = explode( '"', $boundary );
   101 				$boundary = $boundary[1];
   107 				$boundary = $boundary[1];
   102 			}
   108 			}
   103 			if (preg_match('/Subject: /i', $line)) {
   109 			if ( preg_match( '/Subject: /i', $line ) ) {
   104 				$subject = trim($line);
   110 				$subject = trim( $line );
   105 				$subject = substr($subject, 9, strlen($subject) - 9);
   111 				$subject = substr( $subject, 9, strlen( $subject ) - 9 );
   106 				// Captures any text in the subject before $phone_delim as the subject
   112 				// Captures any text in the subject before $phone_delim as the subject
   107 				if ( function_exists('iconv_mime_decode') ) {
   113 				if ( function_exists( 'iconv_mime_decode' ) ) {
   108 					$subject = iconv_mime_decode($subject, 2, get_option('blog_charset'));
   114 					$subject = iconv_mime_decode( $subject, 2, get_option( 'blog_charset' ) );
   109 				} else {
   115 				} else {
   110 					$subject = wp_iso_descrambler($subject);
   116 					$subject = wp_iso_descrambler( $subject );
   111 				}
   117 				}
   112 				$subject = explode($phone_delim, $subject);
   118 				$subject = explode( $phone_delim, $subject );
   113 				$subject = $subject[0];
   119 				$subject = $subject[0];
   114 			}
   120 			}
   115 
   121 
   116 			/*
   122 			/*
   117 			 * Set the author using the email address (From or Reply-To, the last used)
   123 			 * Set the author using the email address (From or Reply-To, the last used)
   118 			 * otherwise use the site admin.
   124 			 * otherwise use the site admin.
   119 			 */
   125 			 */
   120 			if ( ! $author_found && preg_match( '/^(From|Reply-To): /', $line ) ) {
   126 			if ( ! $author_found && preg_match( '/^(From|Reply-To): /', $line ) ) {
   121 				if ( preg_match('|[a-z0-9_.-]+@[a-z0-9_.-]+(?!.*<)|i', $line, $matches) )
   127 				if ( preg_match( '|[a-z0-9_.-]+@[a-z0-9_.-]+(?!.*<)|i', $line, $matches ) ) {
   122 					$author = $matches[0];
   128 					$author = $matches[0];
   123 				else
   129 				} else {
   124 					$author = trim($line);
   130 					$author = trim( $line );
   125 				$author = sanitize_email($author);
   131 				}
   126 				if ( is_email($author) ) {
   132 				$author = sanitize_email( $author );
       
   133 				if ( is_email( $author ) ) {
   127 					/* translators: Post author email address */
   134 					/* translators: Post author email address */
   128 					echo '<p>' . sprintf(__('Author is %s'), $author) . '</p>';
   135 					echo '<p>' . sprintf( __( 'Author is %s' ), $author ) . '</p>';
   129 					$userdata = get_user_by('email', $author);
   136 					$userdata = get_user_by( 'email', $author );
   130 					if ( ! empty( $userdata ) ) {
   137 					if ( ! empty( $userdata ) ) {
   131 						$post_author = $userdata->ID;
   138 						$post_author  = $userdata->ID;
   132 						$author_found = true;
   139 						$author_found = true;
   133 					}
   140 					}
   134 				}
   141 				}
   135 			}
   142 			}
   136 
   143 
   137 			if ( preg_match( '/Date: /i', $line ) ) { // of the form '20 Mar 2002 20:32:37 +0100'
   144 			if ( preg_match( '/Date: /i', $line ) ) { // of the form '20 Mar 2002 20:32:37 +0100'
   138 				$ddate = str_replace( 'Date: ', '', trim( $line ) );
   145 				$ddate         = str_replace( 'Date: ', '', trim( $line ) );
   139 				$ddate = preg_replace( '!\s*\(.+\)\s*$!', '', $ddate );	// remove parenthesised timezone string if it exists, as this confuses strtotime
   146 				$ddate         = preg_replace( '!\s*\(.+\)\s*$!', '', $ddate ); // remove parenthesised timezone string if it exists, as this confuses strtotime
   140 				$ddate_U = strtotime( $ddate );
   147 				$ddate_U       = strtotime( $ddate );
   141 				$post_date = gmdate( 'Y-m-d H:i:s', $ddate_U + $time_difference );
   148 				$post_date     = gmdate( 'Y-m-d H:i:s', $ddate_U + $time_difference );
   142 				$post_date_gmt = gmdate( 'Y-m-d H:i:s', $ddate_U );
   149 				$post_date_gmt = gmdate( 'Y-m-d H:i:s', $ddate_U );
   143 			}
   150 			}
   144 		}
   151 		}
   145 	}
   152 	}
   146 
   153 
   147 	// Set $post_status based on $author_found and on author's publish_posts capability
   154 	// Set $post_status based on $author_found and on author's publish_posts capability
   148 	if ( $author_found ) {
   155 	if ( $author_found ) {
   149 		$user = new WP_User($post_author);
   156 		$user        = new WP_User( $post_author );
   150 		$post_status = ( $user->has_cap('publish_posts') ) ? 'publish' : 'pending';
   157 		$post_status = ( $user->has_cap( 'publish_posts' ) ) ? 'publish' : 'pending';
   151 	} else {
   158 	} else {
   152 		// Author not found in DB, set status to pending. Author already set to admin.
   159 		// Author not found in DB, set status to pending. Author already set to admin.
   153 		$post_status = 'pending';
   160 		$post_status = 'pending';
   154 	}
   161 	}
   155 
   162 
   156 	$subject = trim($subject);
   163 	$subject = trim( $subject );
   157 
   164 
   158 	if ( $content_type == 'multipart/alternative' ) {
   165 	if ( $content_type == 'multipart/alternative' ) {
   159 		$content = explode('--'.$boundary, $content);
   166 		$content = explode( '--' . $boundary, $content );
   160 		$content = $content[2];
   167 		$content = $content[2];
   161 
   168 
   162 		// Match case-insensitive content-transfer-encoding.
   169 		// Match case-insensitive content-transfer-encoding.
   163 		if ( preg_match( '/Content-Transfer-Encoding: quoted-printable/i', $content, $delim) ) {
   170 		if ( preg_match( '/Content-Transfer-Encoding: quoted-printable/i', $content, $delim ) ) {
   164 			$content = explode($delim[0], $content);
   171 			$content = explode( $delim[0], $content );
   165 			$content = $content[1];
   172 			$content = $content[1];
   166 		}
   173 		}
   167 		$content = strip_tags($content, '<img><p><br><i><b><u><em><strong><strike><font><span><div>');
   174 		$content = strip_tags( $content, '<img><p><br><i><b><u><em><strong><strike><font><span><div>' );
   168 	}
   175 	}
   169 	$content = trim($content);
   176 	$content = trim( $content );
   170 
   177 
   171 	/**
   178 	/**
   172 	 * Filters the original content of the email.
   179 	 * Filters the original content of the email.
   173 	 *
   180 	 *
   174 	 * Give Post-By-Email extending plugins full access to the content, either
   181 	 * Give Post-By-Email extending plugins full access to the content, either
   178 	 *
   185 	 *
   179 	 * @param string $content The original email content.
   186 	 * @param string $content The original email content.
   180 	 */
   187 	 */
   181 	$content = apply_filters( 'wp_mail_original_content', $content );
   188 	$content = apply_filters( 'wp_mail_original_content', $content );
   182 
   189 
   183 	if ( false !== stripos($content_transfer_encoding, "quoted-printable") ) {
   190 	if ( false !== stripos( $content_transfer_encoding, 'quoted-printable' ) ) {
   184 		$content = quoted_printable_decode($content);
   191 		$content = quoted_printable_decode( $content );
   185 	}
   192 	}
   186 
   193 
   187 	if ( function_exists('iconv') && ! empty( $charset ) ) {
   194 	if ( function_exists( 'iconv' ) && ! empty( $charset ) ) {
   188 		$content = iconv($charset, get_option('blog_charset'), $content);
   195 		$content = iconv( $charset, get_option( 'blog_charset' ), $content );
   189 	}
   196 	}
   190 
   197 
   191 	// Captures any text in the body after $phone_delim as the body
   198 	// Captures any text in the body after $phone_delim as the body
   192 	$content = explode($phone_delim, $content);
   199 	$content = explode( $phone_delim, $content );
   193 	$content = empty( $content[1] ) ? $content[0] : $content[1];
   200 	$content = empty( $content[1] ) ? $content[0] : $content[1];
   194 
   201 
   195 	$content = trim($content);
   202 	$content = trim( $content );
   196 
   203 
   197 	/**
   204 	/**
   198 	 * Filters the content of the post submitted by email before saving.
   205 	 * Filters the content of the post submitted by email before saving.
   199 	 *
   206 	 *
   200 	 * @since 1.2.0
   207 	 * @since 1.2.0
   201 	 *
   208 	 *
   202 	 * @param string $content The email content.
   209 	 * @param string $content The email content.
   203 	 */
   210 	 */
   204 	$post_content = apply_filters( 'phone_content', $content );
   211 	$post_content = apply_filters( 'phone_content', $content );
   205 
   212 
   206 	$post_title = xmlrpc_getposttitle($content);
   213 	$post_title = xmlrpc_getposttitle( $content );
   207 
   214 
   208 	if ($post_title == '') $post_title = $subject;
   215 	if ( $post_title == '' ) {
   209 
   216 		$post_title = $subject;
   210 	$post_category = array(get_option('default_email_category'));
   217 	}
   211 
   218 
   212 	$post_data = compact('post_content','post_title','post_date','post_date_gmt','post_author','post_category', 'post_status');
   219 	$post_category = array( get_option( 'default_email_category' ) );
   213 	$post_data = wp_slash($post_data);
   220 
   214 
   221 	$post_data = compact( 'post_content', 'post_title', 'post_date', 'post_date_gmt', 'post_author', 'post_category', 'post_status' );
   215 	$post_ID = wp_insert_post($post_data);
   222 	$post_data = wp_slash( $post_data );
   216 	if ( is_wp_error( $post_ID ) )
   223 
       
   224 	$post_ID = wp_insert_post( $post_data );
       
   225 	if ( is_wp_error( $post_ID ) ) {
   217 		echo "\n" . $post_ID->get_error_message();
   226 		echo "\n" . $post_ID->get_error_message();
       
   227 	}
   218 
   228 
   219 	// We couldn't post, for whatever reason. Better move forward to the next email.
   229 	// We couldn't post, for whatever reason. Better move forward to the next email.
   220 	if ( empty( $post_ID ) )
   230 	if ( empty( $post_ID ) ) {
   221 		continue;
   231 		continue;
       
   232 	}
   222 
   233 
   223 	/**
   234 	/**
   224 	 * Fires after a post submitted by email is published.
   235 	 * Fires after a post submitted by email is published.
   225 	 *
   236 	 *
   226 	 * @since 1.2.0
   237 	 * @since 1.2.0
   230 	do_action( 'publish_phone', $post_ID );
   241 	do_action( 'publish_phone', $post_ID );
   231 
   242 
   232 	echo "\n<p><strong>" . __( 'Author:' ) . '</strong> ' . esc_html( $post_author ) . '</p>';
   243 	echo "\n<p><strong>" . __( 'Author:' ) . '</strong> ' . esc_html( $post_author ) . '</p>';
   233 	echo "\n<p><strong>" . __( 'Posted title:' ) . '</strong> ' . esc_html( $post_title ) . '</p>';
   244 	echo "\n<p><strong>" . __( 'Posted title:' ) . '</strong> ' . esc_html( $post_title ) . '</p>';
   234 
   245 
   235 	if(!$pop3->delete($i)) {
   246 	if ( ! $pop3->delete( $i ) ) {
   236 		echo '<p>' . sprintf(
   247 		echo '<p>' . sprintf(
   237 			/* translators: %s: POP3 error */
   248 			/* translators: %s: POP3 error */
   238 			__( 'Oops: %s' ),
   249 			__( 'Oops: %s' ),
   239 			esc_html( $pop3->ERROR )
   250 			esc_html( $pop3->ERROR )
   240 		) . '</p>';
   251 		) . '</p>';
   245 			/* translators: %s: the message ID */
   256 			/* translators: %s: the message ID */
   246 			__( 'Mission complete. Message %s deleted.' ),
   257 			__( 'Mission complete. Message %s deleted.' ),
   247 			'<strong>' . $i . '</strong>'
   258 			'<strong>' . $i . '</strong>'
   248 		) . '</p>';
   259 		) . '</p>';
   249 	}
   260 	}
   250 
       
   251 }
   261 }
   252 
   262 
   253 $pop3->quit();
   263 $pop3->quit();