public function testBadMailAddresses()
 {
     $address1 = MailAddress::create()->setAddress("vasya@example.com");
     $address2 = MailAddress::create()->setAddress("va sya@example.com");
     try {
         $address1->toString();
         $address2->toString();
         $this->fail();
     } catch (WrongArgumentException $e) {
         //pass
     }
 }
Example #2
0
 /**
  * Send an e-mail to this user's account. Does not check for
  * confirmed status or validity.
  *
  * @param string $subject Message subject
  * @param string $body Message body
  * @param User|null $from Optional sending user; if unspecified, default
  *   $wgPasswordSender will be used.
  * @param string $replyto Reply-To address
  * @return Status
  */
 public function sendMail($subject, $body, $from = null, $replyto = null)
 {
     global $wgPasswordSender;
     if ($from instanceof User) {
         $sender = MailAddress::newFromUser($from);
     } else {
         $sender = new MailAddress($wgPasswordSender, wfMessage('emailsender')->inContentLanguage()->text());
     }
     $to = MailAddress::newFromUser($this);
     return UserMailer::send($to, $sender, $subject, $body, array('replyTo' => $replyto));
 }
Example #3
0
 /**
  * Really send a mail. Permissions should have been checked using
  * getPermissionsError(). It is probably also a good
  * idea to check the edit token and ping limiter in advance.
  *
  * @param array $data
  * @param IContextSource $context
  * @return Status|string|bool Status object, or potentially a String on error
  * or maybe even true on success if anything uses the EmailUser hook.
  */
 public static function submit(array $data, IContextSource $context)
 {
     $config = $context->getConfig();
     $target = self::getTarget($data['Target']);
     if (!$target instanceof User) {
         // Messages used here: notargettext, noemailtext, nowikiemailtext
         return $context->msg($target . 'text')->parseAsBlock();
     }
     $to = MailAddress::newFromUser($target);
     $from = MailAddress::newFromUser($context->getUser());
     $subject = $data['Subject'];
     $text = $data['Text'];
     // Add a standard footer and trim up trailing newlines
     $text = rtrim($text) . "\n\n-- \n";
     $text .= $context->msg('emailuserfooter', $from->name, $to->name)->inContentLanguage()->text();
     $error = '';
     if (!Hooks::run('EmailUser', array(&$to, &$from, &$subject, &$text, &$error))) {
         return $error;
     }
     if ($config->get('UserEmailUseReplyTo')) {
         /**
          * Put the generic wiki autogenerated address in the From:
          * header and reserve the user for Reply-To.
          *
          * This is a bit ugly, but will serve to differentiate
          * wiki-borne mails from direct mails and protects against
          * SPF and bounce problems with some mailers (see below).
          */
         $mailFrom = new MailAddress($config->get('PasswordSender'), wfMessage('emailsender')->inContentLanguage()->text());
         $replyTo = $from;
     } else {
         /**
          * Put the sending user's e-mail address in the From: header.
          *
          * This is clean-looking and convenient, but has issues.
          * One is that it doesn't as clearly differentiate the wiki mail
          * from "directly" sent mails.
          *
          * Another is that some mailers (like sSMTP) will use the From
          * address as the envelope sender as well. For open sites this
          * can cause mails to be flunked for SPF violations (since the
          * wiki server isn't an authorized sender for various users'
          * domains) as well as creating a privacy issue as bounces
          * containing the recipient's e-mail address may get sent to
          * the sending user.
          */
         $mailFrom = $from;
         $replyTo = null;
     }
     $status = UserMailer::send($to, $mailFrom, $subject, $text, array('replyTo' => $replyTo));
     if (!$status->isGood()) {
         return $status;
     } else {
         // if the user requested a copy of this mail, do this now,
         // unless they are emailing themselves, in which case one
         // copy of the message is sufficient.
         if ($data['CCMe'] && $to != $from) {
             $cc_subject = $context->msg('emailccsubject')->rawParams($target->getName(), $subject)->text();
             // target and sender are equal, because this is the CC for the sender
             Hooks::run('EmailUserCC', array(&$from, &$from, &$cc_subject, &$text));
             $ccStatus = UserMailer::send($from, $from, $cc_subject, $text);
             $status->merge($ccStatus);
         }
         Hooks::run('EmailUserComplete', array($to, $from, $subject, $text));
         return $status;
     }
 }
Example #4
0
 /**
  * Does the per-user customizations to a notification e-mail (name,
  * timestamp in proper timezone, etc) and sends it out.
  * Returns true if the mail was sent successfully.
  *
  * @param User $watchingUser
  * @return bool
  * @private
  */
 function sendPersonalised($watchingUser)
 {
     global $wgContLang, $wgEnotifUseRealName;
     // From the PHP manual:
     //   Note: The to parameter cannot be an address in the form of
     //   "Something <someone@example.com>". The mail command will not parse
     //   this properly while talking with the MTA.
     $to = MailAddress::newFromUser($watchingUser);
     # $PAGEEDITDATE is the time and date of the page change
     # expressed in terms of individual local time of the notification
     # recipient, i.e. watching user
     $body = str_replace(array('$WATCHINGUSERNAME', '$PAGEEDITDATE', '$PAGEEDITTIME'), array($wgEnotifUseRealName && $watchingUser->getRealName() !== '' ? $watchingUser->getRealName() : $watchingUser->getName(), $wgContLang->userDate($this->timestamp, $watchingUser), $wgContLang->userTime($this->timestamp, $watchingUser)), $this->body);
     return UserMailer::send($to, $this->from, $this->subject, $body, $this->replyto);
 }
Example #5
0
 function execute($para)
 {
     global $wgRequest, $wgOut, $wgUser, $wgWhiteListOverride, $wgWhiteListManagerGroup, $wgWhiteListRestrictedGroup, $wgSitename;
     $dbr = wfGetDB(DB_SLAVE);
     if (!isset($para) || $para == '') {
         $user = $wgUser;
     } else {
         $user = WhiteListUserFromId($user);
     }
     $this->setHeaders();
     $wgOut->setPagetitle(wfMsg('whitelist'));
     if (!in_array($wgWhiteListRestrictedGroup, $user->getGroups())) {
         if (!($userName = $user->getRealName())) {
             $userName = $user->getName();
         }
         $wgOut->addWikiText(wfMsg('whitelistnonrestricted', $userName));
         return true;
     }
     if ($wgRequest->getVal('submit', '') == wfMsg('whitelistnewtableprocess')) {
         $sender = new MailAddress($wgUser->getEmail(), $wgUser->getRealName());
         $to = '';
         if (constant("MW_USER_VERSION") < 4) {
             $to = new User();
             $to->mId = $wgRequest->getint('manager', 0);
         } else {
             $to = WhiteListUserFromId($wgRequest->getint('manager', 0));
         }
         // FIXME: I think this mail will be sent in the wrong language.
         $requestedPages = $wgRequest->getVal('newPages');
         $requestedPagesCount = count($requestedPages);
         $to->sendMail("[{$wgSitename}] " . wfMsg('whitelistrequest'), wfMsgExt('whitelistrequestmsg', array('parsemag'), $wgUser->getRealName(), $requestedPages, $requestedPagesCount), $sender->toString(), null, 'WhiteList');
         $wgOut->addWikiText(wfMsg('whitelistrequestconf', $to->getRealName()));
         $wgOut->addWikiText("");
     }
     $wgOut->addHTML("<table cellspacing=0 cellpadding=2 border=1 width=100%><tr>");
     $wgOut->addHTML("<th>" . wfMsg('whitelistpagelist', $user->getRealName()) . "</th><th>" . wfMsg('whitelistrequest') . "</th>");
     $wgOut->addHTML("</tr><tr><td width=30%>");
     $res = WhiteListEdit::contractorWhiteListTable($dbr, $user->getId());
     for ($row = $dbr->fetchObject($res); $row; $row = $dbr->fetchObject($res)) {
         WhiteListEdit::DisplayWildCardMatches($row->wl_page_title, $row->wl_page_title, 0);
     }
     $dbr->freeResult($res);
     $pages = array();
     foreach ($wgWhiteListOverride['always']['read'] as $page) {
         array_push($pages, $page);
     }
     foreach ($wgWhiteListOverride['always']['edit'] as $page) {
         array_push($pages, $page);
     }
     sort($pages);
     foreach ($pages as $page) {
         WhiteListEdit::DisplayWildCardMatches($page, $page, 0);
     }
     $wgOut->addHTML("</td><td valign=top>");
     $wgOut->addHTML("<table cellspacing=0 cellpadding=2 border=0 width=100%><tr><td align='right'>{$wgWhiteListManagerGroup}:</td><td>");
     $wgOut->addHTML("<form method=\"post\">");
     $wgOut->addHTML('<select name="manager">');
     $users = array();
     $dbr->begin();
     $res = $dbr->select('user_groups', 'ug_user', array('ug_group' => $wgWhiteListManagerGroup), __METHOD__);
     $dbr->commit();
     for ($row = $dbr->fetchObject($res); $row; $row = $dbr->fetchObject($res)) {
         $u = WhiteListUserFromID($row->ug_user);
         $users[$u->getRealName()] = $row->ug_user;
     }
     $dbr->freeResult($res);
     ksort($users);
     foreach ($users as $name => $id) {
         $wgOut->addHTML("<option value=\"{$id}\">" . $name . "</option>");
     }
     $wgOut->addHTML('</select> ');
     $wgOut->addHTML("</td></tr><tr><td align='right'>" . wfMsg('mywhitelistpages') . ":</td><td>");
     $wgOut->addHTML("<textarea name='newPages' cols=40 rows=5></textarea>");
     $wgOut->addHTML("</td></tr><tr><td colspan=2><center>");
     $wgOut->addHTML("<input type='submit' name='submit' value='" . wfMsg('whitelistnewtableprocess') . "' />");
     $wgOut->addHTML("</form>");
     $wgOut->addHTML("</center></td></tr></table>");
     $wgOut->addHTML("</td></tr></table>");
     $wgOut->addHTML("</td></tr></table>");
 }
Example #6
0
 /**
  * Helper function fo UserMailer::send() which does the actual sending. It expects a $to
  * list which the UserMailerSplitTo hook would not split further.
  * @param MailAddress[] $to Array of recipients' email addresses
  * @param MailAddress $from Sender's email
  * @param string $subject Email's subject.
  * @param string $body Email's text or Array of two strings to be the text and html bodies
  * @param array $options:
  * 		'replyTo' MailAddress
  * 		'contentType' string default 'text/plain; charset=UTF-8'
  * 		'headers' array Extra headers to set
  *
  * @throws MWException
  * @throws Exception
  * @return Status
  */
 protected static function sendInternal(array $to, MailAddress $from, $subject, $body, $options = array())
 {
     global $wgSMTP, $wgEnotifMaxRecips, $wgAdditionalMailParams;
     $mime = null;
     $replyto = isset($options['replyTo']) ? $options['replyTo'] : null;
     $contentType = isset($options['contentType']) ? $options['contentType'] : 'text/plain; charset=UTF-8';
     $headers = isset($options['headers']) ? $options['headers'] : array();
     // Allow transformation of content, such as encrypting/signing
     $error = false;
     if (!Hooks::run('UserMailerTransformContent', array($to, $from, &$body, &$error))) {
         if ($error) {
             return Status::newFatal('php-mail-error', $error);
         } else {
             return Status::newFatal('php-mail-error-unknown');
         }
     }
     /**
      * Forge email headers
      * -------------------
      *
      * WARNING
      *
      * DO NOT add To: or Subject: headers at this step. They need to be
      * handled differently depending upon the mailer we are going to use.
      *
      * To:
      *  PHP mail() first argument is the mail receiver. The argument is
      *  used as a recipient destination and as a To header.
      *
      *  PEAR mailer has a recipient argument which is only used to
      *  send the mail. If no To header is given, PEAR will set it to
      *  to 'undisclosed-recipients:'.
      *
      *  NOTE: To: is for presentation, the actual recipient is specified
      *  by the mailer using the Rcpt-To: header.
      *
      * Subject:
      *  PHP mail() second argument to pass the subject, passing a Subject
      *  as an additional header will result in a duplicate header.
      *
      *  PEAR mailer should be passed a Subject header.
      *
      * -- hashar 20120218
      */
     $headers['From'] = $from->toString();
     $returnPath = $from->address;
     $extraParams = $wgAdditionalMailParams;
     // Hook to generate custom VERP address for 'Return-Path'
     Hooks::run('UserMailerChangeReturnPath', array($to, &$returnPath));
     // Add the envelope sender address using the -f command line option when PHP mail() is used.
     // Will default to the $from->address when the UserMailerChangeReturnPath hook fails and the
     // generated VERP address when the hook runs effectively.
     $extraParams .= ' -f ' . $returnPath;
     $headers['Return-Path'] = $returnPath;
     if ($replyto) {
         $headers['Reply-To'] = $replyto->toString();
     }
     $headers['Date'] = MWTimestamp::getLocalInstance()->format('r');
     $headers['Message-ID'] = self::makeMsgId();
     $headers['X-Mailer'] = 'MediaWiki mailer';
     $headers['List-Unsubscribe'] = '<' . SpecialPage::getTitleFor('Preferences')->getFullURL('', false, PROTO_CANONICAL) . '>';
     // Line endings need to be different on Unix and Windows due to
     // the bug described at http://trac.wordpress.org/ticket/2603
     if (wfIsWindows()) {
         $endl = "\r\n";
     } else {
         $endl = "\n";
     }
     if (is_array($body)) {
         // we are sending a multipart message
         wfDebug("Assembling multipart mime email\n");
         if (!stream_resolve_include_path('Mail/mime.php')) {
             wfDebug("PEAR Mail_Mime package is not installed. Falling back to text email.\n");
             // remove the html body for text email fall back
             $body = $body['text'];
         } else {
             // Check if pear/mail_mime is already loaded (via composer)
             if (!class_exists('Mail_mime')) {
                 require_once 'Mail/mime.php';
             }
             if (wfIsWindows()) {
                 $body['text'] = str_replace("\n", "\r\n", $body['text']);
                 $body['html'] = str_replace("\n", "\r\n", $body['html']);
             }
             $mime = new Mail_mime(array('eol' => $endl, 'text_charset' => 'UTF-8', 'html_charset' => 'UTF-8'));
             $mime->setTXTBody($body['text']);
             $mime->setHTMLBody($body['html']);
             $body = $mime->get();
             // must call get() before headers()
             $headers = $mime->headers($headers);
         }
     }
     if ($mime === null) {
         // sending text only, either deliberately or as a fallback
         if (wfIsWindows()) {
             $body = str_replace("\n", "\r\n", $body);
         }
         $headers['MIME-Version'] = '1.0';
         $headers['Content-type'] = is_null($contentType) ? 'text/plain; charset=UTF-8' : $contentType;
         $headers['Content-transfer-encoding'] = '8bit';
     }
     // allow transformation of MIME-encoded message
     if (!Hooks::run('UserMailerTransformMessage', array($to, $from, &$subject, &$headers, &$body, &$error))) {
         if ($error) {
             return Status::newFatal('php-mail-error', $error);
         } else {
             return Status::newFatal('php-mail-error-unknown');
         }
     }
     $ret = Hooks::run('AlternateUserMailer', array($headers, $to, $from, $subject, $body));
     if ($ret === false) {
         // the hook implementation will return false to skip regular mail sending
         return Status::newGood();
     } elseif ($ret !== true) {
         // the hook implementation will return a string to pass an error message
         return Status::newFatal('php-mail-error', $ret);
     }
     if (is_array($wgSMTP)) {
         // Check if pear/mail is already loaded (via composer)
         if (!class_exists('Mail')) {
             // PEAR MAILER
             if (!stream_resolve_include_path('Mail.php')) {
                 throw new MWException('PEAR mail package is not installed');
             }
             require_once 'Mail.php';
         }
         MediaWiki\suppressWarnings();
         // Create the mail object using the Mail::factory method
         $mail_object =& Mail::factory('smtp', $wgSMTP);
         if (PEAR::isError($mail_object)) {
             wfDebug("PEAR::Mail factory failed: " . $mail_object->getMessage() . "\n");
             MediaWiki\restoreWarnings();
             return Status::newFatal('pear-mail-error', $mail_object->getMessage());
         }
         wfDebug("Sending mail via PEAR::Mail\n");
         $headers['Subject'] = self::quotedPrintable($subject);
         // When sending only to one recipient, shows it its email using To:
         if (count($to) == 1) {
             $headers['To'] = $to[0]->toString();
         }
         // Split jobs since SMTP servers tends to limit the maximum
         // number of possible recipients.
         $chunks = array_chunk($to, $wgEnotifMaxRecips);
         foreach ($chunks as $chunk) {
             $status = self::sendWithPear($mail_object, $chunk, $headers, $body);
             // FIXME : some chunks might be sent while others are not!
             if (!$status->isOK()) {
                 MediaWiki\restoreWarnings();
                 return $status;
             }
         }
         MediaWiki\restoreWarnings();
         return Status::newGood();
     } else {
         // PHP mail()
         if (count($to) > 1) {
             $headers['To'] = 'undisclosed-recipients:;';
         }
         $headers = self::arrayToHeaderString($headers, $endl);
         wfDebug("Sending mail via internal mail() function\n");
         self::$mErrorString = '';
         $html_errors = ini_get('html_errors');
         ini_set('html_errors', '0');
         set_error_handler('UserMailer::errorHandler');
         try {
             $safeMode = wfIniGetBool('safe_mode');
             foreach ($to as $recip) {
                 if ($safeMode) {
                     $sent = mail($recip, self::quotedPrintable($subject), $body, $headers);
                 } else {
                     $sent = mail($recip, self::quotedPrintable($subject), $body, $headers, $extraParams);
                 }
             }
         } catch (Exception $e) {
             restore_error_handler();
             throw $e;
         }
         restore_error_handler();
         ini_set('html_errors', $html_errors);
         if (self::$mErrorString) {
             wfDebug("Error sending mail: " . self::$mErrorString . "\n");
             return Status::newFatal('php-mail-error', self::$mErrorString);
         } elseif (!$sent) {
             // mail function only tells if there's an error
             wfDebug("Unknown error sending mail\n");
             return Status::newFatal('php-mail-error-unknown');
         } else {
             return Status::newGood();
         }
     }
 }
Example #7
0
 /**
  * Does the per-user customizations to a notification e-mail (name,
  * timestamp in proper timezone, etc) and sends it out.
  * Returns true if the mail was sent successfully.
  *
  * @param User $watchingUser
  * @param string $source
  * @return bool
  * @private
  */
 function sendPersonalised($watchingUser, $source)
 {
     global $wgContLang, $wgEnotifUseRealName;
     // From the PHP manual:
     //   Note: The to parameter cannot be an address in the form of
     //   "Something <someone@example.com>". The mail command will not parse
     //   this properly while talking with the MTA.
     $to = MailAddress::newFromUser($watchingUser);
     # $PAGEEDITDATE is the time and date of the page change
     # expressed in terms of individual local time of the notification
     # recipient, i.e. watching user
     $body = str_replace(array('$WATCHINGUSERNAME', '$PAGEEDITDATE', '$PAGEEDITTIME'), array($wgEnotifUseRealName && $watchingUser->getRealName() !== '' ? $watchingUser->getRealName() : $watchingUser->getName(), $wgContLang->userDate($this->timestamp, $watchingUser), $wgContLang->userTime($this->timestamp, $watchingUser)), $this->body);
     $headers = array();
     if ($source === self::WATCHLIST) {
         $headers['List-Help'] = 'https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Watchlist';
     }
     return UserMailer::send($to, $this->from, $this->subject, $body, array('replyTo' => $this->replyto, 'headers' => $headers));
 }
 function doSubmit()
 {
     global $wgOut, $wgContactSender, $wgContactSenderName;
     #TODO: check captcha
     $fname = 'EmailContactForm::doSubmit';
     wfDebug("{$fname}: start\n");
     $to = new MailAddress($this->target);
     $from = new MailAddress($wgContactSender, $wgContactSenderName);
     $replyto = $this->fromaddress ? new MailAddress($this->fromaddress, $this->fromname) : NULL;
     $subject = trim($this->subject);
     if ($subject === "") {
         $subject = wfMsgForContent("contactpage-defsubject");
     }
     if ($this->fromname !== "") {
         $subject = wfMsgForContent("contactpage-subject-and-sender", $subject, $this->fromname);
     }
     if (wfRunHooks('ContactForm', array(&$to, &$replyto, &$subject, &$this->text))) {
         wfDebug("{$fname}: sending mail from " . $from->toString() . " to " . $to->toString() . " replyto " . ($replyto == null ? '-/-' : $replyto->toString()) . "\n");
         #HACK: in MW 1.9, replyto must be a string, in MW 1.0, it must be an object!
         $ver = preg_replace('![^\\d._+]!', '', $GLOBALS['wgVersion']);
         $replyaddr = $replyto == null ? NULL : version_compare($ver, '1.10', '<') ? $replyto->toString() : $replyto;
         $mailResult = userMailer($to, $from, $subject, $this->text, $replyaddr);
         if (WikiError::isError($mailResult)) {
             $wgOut->addHTML(wfMsg("usermailererror") . $mailResult);
         } else {
             // if the user requested a copy of this mail, do this now,
             // unless they are emailing themselves, in which case one copy of the message is sufficient.
             if ($this->cc_me && $replyto) {
                 $cc_subject = wfMsg('emailccsubject', $this->target->getName(), $subject);
                 if (wfRunHooks('ContactForm', array(&$from, &$replyto, &$cc_subject, &$this->text))) {
                     wfDebug("{$fname}: sending cc mail from " . $from->toString() . " to " . $replyto->toString() . "\n");
                     $ccResult = userMailer($replyto, $from, $cc_subject, $this->text);
                     if (WikiError::isError($ccResult)) {
                         // At this stage, the user's CC mail has failed, but their
                         // original mail has succeeded. It's unlikely, but still, what to do?
                         // We can either show them an error, or we can say everything was fine,
                         // or we can say we sort of failed AND sort of succeeded. Of these options,
                         // simply saying there was an error is probably best.
                         $wgOut->addHTML(wfMsg("usermailererror") . $ccResult);
                         return;
                     }
                 }
             }
             wfDebug("{$fname}: success\n");
             $titleObj = SpecialPage::getTitleFor("Contact");
             $wgOut->redirect($titleObj->getFullURL("action=success"));
             wfRunHooks('ContactFromComplete', array($to, $replyto, $subject, $this->text));
         }
     }
     wfDebug("{$fname}: end\n");
 }
Example #9
0
 /**
  * This function will perform a direct (authenticated) login to
  * a SMTP Server to use for mail relaying if 'wgSMTP' specifies an
  * array of parameters. It requires PEAR:Mail to do that.
  * Otherwise it just uses the standard PHP 'mail' function.
  *
  * @param MailAddress $to : recipient's email (or an array of them)
  * @param MailAddress $from : sender's email
  * @param String $subject : email's subject.
  * @param String $body : email's text.
  * $body can be array with text and html version of email message, and also can contain attachements
  * $body = array('text' => 'Email text', 'html' => '<b>Email text</b>')
  * @param MailAddress $replyTo : optional reply-to email (default: null).
  * @param String $contentType : optional custom Content-Type
  * @param String $category : optional category for statistic
  * @param int $priority : optional priority for email
  * @param Array $attachments : optional list of files to send as attachments
  *
  * @return Status object
  * @throws MWException
  */
 public static function send(MailAddress $to, MailAddress $from, $subject, $body, MailAddress $replyTo = null, $contentType = null, $category = 'UserMailer', $priority = 0, $attachments = [])
 {
     if (!is_array($to)) {
         $to = [$to];
     }
     # Make sure we have at least one address
     $has_address = false;
     foreach ($to as $u) {
         if ($u->address) {
             $has_address = true;
             break;
         }
     }
     if (!$has_address) {
         return Status::newFatal('user-mail-no-addy');
     }
     wfRunHooks('UserMailerSend', [&$to]);
     # Forge email headers
     # -------------------
     #
     # WARNING
     #
     # DO NOT add To: or Subject: headers at this step. They need to be
     # handled differently depending upon the mailer we are going to use.
     #
     # To:
     #  PHP mail() first argument is the mail receiver. The argument is
     #  used as a recipient destination and as a To header.
     #
     #  PEAR mailer has a recipient argument which is only used to
     #  send the mail. If no To header is given, PEAR will set it to
     #  to 'undisclosed-recipients:'.
     #
     #  NOTE: To: is for presentation, the actual recipient is specified
     #  by the mailer using the Rcpt-To: header.
     #
     # Subject:
     #  PHP mail() second argument to pass the subject, passing a Subject
     #  as an additional header will result in a duplicate header.
     #
     #  PEAR mailer should be passed a Subject header.
     #
     # -- hashar 20120218
     $headers['From'] = $from->toString();
     $headers['Return-Path'] = $from->address;
     if ($replyTo && $replyTo instanceof MailAddress) {
         $headers['Reply-To'] = $replyTo->toString();
     }
     $headers['Date'] = date('r');
     $headers['MIME-Version'] = '1.0';
     if (empty($attachments)) {
         $headers['Content-Type'] = is_null($contentType) ? 'text/plain; charset=UTF-8' : $contentType;
         $headers['Content-Transfer-Encoding'] = '8bit';
     }
     $headers['Message-ID'] = self::makeMsgId();
     $headers['X-Mailer'] = 'MediaWiki mailer';
     $headers['X-Msg-Category'] = $category;
     if ($priority) {
         $headers['X-Priority'] = $priority;
     }
     $ret = wfRunHooks('AlternateUserMailer', [$headers, $to, $from, $subject, $body, $priority, $attachments]);
     if ($ret === false) {
         return Status::newGood();
     } elseif ($ret !== true) {
         return Status::newFatal('php-mail-error', $ret);
     }
     # MoLi: body can be an array with text and html message
     # MW core uses only text version of email message, so $body as array should be used only with AlternateUserMailer hook
     if (is_array($body) && isset($body['text'])) {
         $body = $body['text'];
     }
     if (is_array(F::app()->wg->SMTP)) {
         #
         # PEAR MAILER
         #
         if (function_exists('stream_resolve_include_path')) {
             $found = stream_resolve_include_path('Mail.php');
         } else {
             $found = Fallback::stream_resolve_include_path('Mail.php');
         }
         if (!$found) {
             throw new MWException('PEAR mail package is not installed');
         }
         require_once 'Mail.php';
         wfSuppressWarnings();
         // Create the mail object using the Mail::factory method
         $mail_object =& Mail::factory('smtp', F::app()->wg->SMTP);
         if (PEAR::isError($mail_object)) {
             wfDebug("PEAR::Mail factory failed: " . $mail_object->getMessage() . "\n");
             wfRestoreWarnings();
             return Status::newFatal('pear-mail-error', $mail_object->getMessage());
         }
         wfDebug("Sending mail via PEAR::Mail\n");
         $headers['Subject'] = self::quotedPrintable($subject);
         # When sending only to one recipient, shows it its email using To:
         if (count($to) == 1) {
             $headers['To'] = $to[0]->toString();
         }
         # Split jobs since SMTP servers tends to limit the maximum
         # number of possible recipients.
         $chunks = array_chunk($to, F::app()->wg->EnotifMaxRecips);
         foreach ($chunks as $chunk) {
             if (!wfRunHooks('ComposeMail', [$chunk, &$body, &$headers])) {
                 continue;
             }
             $status = self::sendWithPear($mail_object, $chunk, $headers, $body);
             # FIXME : some chunks might be sent while others are not!
             if (!$status->isOK()) {
                 wfRestoreWarnings();
                 return $status;
             }
         }
         wfRestoreWarnings();
         return Status::newGood();
     } else {
         #
         # PHP mail()
         #
         # Line endings need to be different on Unix and Windows due to
         # the bug described at http://trac.wordpress.org/ticket/2603
         if (wfIsWindows()) {
             $body = str_replace("\n", "\r\n", $body);
             $endl = "\r\n";
         } else {
             $endl = "\n";
         }
         if (count($to) > 1) {
             $headers['To'] = 'undisclosed-recipients:;';
         }
         $headers = self::arrayToHeaderString($headers, $endl);
         wfDebug("Sending mail via internal mail() function\n");
         self::$mErrorString = '';
         $html_errors = ini_get('html_errors');
         ini_set('html_errors', '0');
         $safeMode = wfIniGetBool('safe_mode');
         foreach ($to as $recip) {
             if (!wfRunHooks('ComposeMail', array($recip, &$body, &$headers))) {
                 continue;
             }
             if ($safeMode) {
                 $sent = mail($recip, self::quotedPrintable($subject), $body, $headers);
             } else {
                 $sent = mail($recip, self::quotedPrintable($subject), $body, $headers, F::app()->wg->AdditionalMailParams);
             }
         }
         ini_set('html_errors', $html_errors);
         if (self::$mErrorString) {
             wfDebug("Error sending mail: " . self::$mErrorString . "\n");
             return Status::newFatal('php-mail-error', self::$mErrorString);
         } elseif (!$sent) {
             // mail function only tells if there's an error
             wfDebug("Unknown error sending mail\n");
             return Status::newFatal('php-mail-error-unknown');
         } else {
             return Status::newGood();
         }
     }
 }
 function doSubmit()
 {
     global $wgOut, $wgUser;
     global $wgUserEmailUseReplyTo, $wgPasswordSender;
     global $wgContactSender, $wgContactSenderName, $wgContactIncludeIP;
     $csender = $wgContactSender ? $wgContactSender : $wgPasswordSender;
     $cname = $wgContactSenderName;
     $senderIP = wfGetIP();
     wfDebug(__METHOD__ . ": start\n");
     $targetAddress = new MailAddress($this->target);
     $replyto = null;
     $contactSender = new MailAddress($csender, $cname);
     if (!$this->fromaddress) {
         $submitterAddress = $contactSender;
     } else {
         $submitterAddress = new MailAddress($this->fromaddress, $this->fromname);
         if ($wgUserEmailUseReplyTo) {
             $replyto = $submitterAddress;
         }
     }
     $subject = trim($this->subject);
     if ($subject === '') {
         $subject = wfMsgForContent('contactpage-defsubject');
     }
     $includeIP = $wgContactIncludeIP && ($this->includeIP || $wgUser->isAnon());
     if ($this->fromname !== '') {
         if ($includeIP) {
             $subject = wfMsgForContent('contactpage-subject-and-sender-withip', $subject, $this->fromname, $senderIP);
         } else {
             $subject = wfMsgForContent('contactpage-subject-and-sender', $subject, $this->fromname);
         }
     } elseif ($this->fromaddress !== '') {
         if ($includeIP) {
             $subject = wfMsgForContent('contactpage-subject-and-sender-withip', $subject, $this->fromaddress, $senderIP);
         } else {
             $subject = wfMsgForContent('contactpage-subject-and-sender', $subject, $this->fromaddress);
         }
     } elseif ($includeIP) {
         $subject = wfMsgForContent('contactpage-subject-and-sender', $subject, $senderIP);
     }
     if (!wfRunHooks('ContactForm', array(&$targetAddress, &$replyto, &$subject, &$this->text, $this->formType))) {
         wfDebug(__METHOD__ . ": aborted by hook\n");
         return;
     }
     wfDebug(__METHOD__ . ": sending mail from " . $submitterAddress->toString() . " to " . $targetAddress->toString() . " replyto " . ($replyto == null ? '-/-' : $replyto->toString()) . "\n");
     $mailResult = UserMailer::send($targetAddress, $submitterAddress, $subject, $this->text, $replyto);
     if (WikiError::isError($mailResult)) {
         $wgOut->addWikiMsg('usermailererror') . $mailResult->getMessage();
         wfDebug(__METHOD__ . ": got error from UserMailer: " . $mailResult->getMessage() . "\n");
         return;
     }
     // if the user requested a copy of this mail, do this now,
     // unless they are emailing themselves, in which case one copy of the message is sufficient.
     if ($this->cc_me && $this->fromaddress) {
         $cc_subject = wfMsg('emailccsubject', $this->target->getName(), $subject);
         if (wfRunHooks('ContactForm', array(&$submitterAddress, &$contactSender, &$cc_subject, &$this->text, $this->formType))) {
             wfDebug(__METHOD__ . ": sending cc mail from " . $contactSender->toString() . " to " . $submitterAddress->toString() . "\n");
             $ccResult = UserMailer::send($submitterAddress, $contactSender, $cc_subject, $this->text);
             if (WikiError::isError($ccResult)) {
                 // At this stage, the user's CC mail has failed, but their
                 // original mail has succeeded. It's unlikely, but still, what to do?
                 // We can either show them an error, or we can say everything was fine,
                 // or we can say we sort of failed AND sort of succeeded. Of these options,
                 // simply saying there was an error is probably best.
                 $wgOut->addWikiText(wfMsg('usermailererror') . $ccResult);
                 return;
             }
         }
     }
     wfDebug(__METHOD__ . ": success\n");
     $titleObj = SpecialPage::getTitleFor('Contact');
     $wgOut->redirect($titleObj->getFullURL('action=success'));
     wfRunHooks('ContactFromComplete', array($targetAddress, $replyto, $subject, $this->text));
     wfDebug(__METHOD__ . ": end\n");
 }
Example #11
0
/**
 * This function will perform a direct (authenticated) login to
 * a SMTP Server to use for mail relaying if 'wgSMTP' specifies an
 * array of parameters. It requires PEAR:Mail to do that.
 * Otherwise it just uses the standard PHP 'mail' function.
 *
 * @param $to MailAddress: recipient's email
 * @param $from MailAddress: sender's email
 * @param $subject String: email's subject.
 * @param $body String: email's text.
 * @param $replyto String: optional reply-to email (default: false).
 */
function userMailer($to, $from, $subject, $body, $replyto = false)
{
    global $wgUser, $wgSMTP, $wgOutputEncoding, $wgErrorString;
    // WERELATE - if mail from WeRelate system, set to WeRelate donotreply@werelate.org; otherwise set to {name} werelate-user@werelate.org
    // this is done because Amazon SES requires validating all sender emails, and we don't want to do that for each user
    // TODO: this needs to be parameterized so other websites can enter their own from addresses
    if (substr($from->address, -13) === '@werelate.org' && ($from->name === 'WeRelateAdmin' || !$from->name)) {
        $replyto = '';
        $from = new MailAddress('donotreply@werelate.org', 'WeRelate');
    } else {
        $replyto = $from->toString();
        $from = new MailAddress('werelate-user@werelate.org', $from->name);
    }
    if (is_array($wgSMTP)) {
        require_once 'Mail.php';
        $timestamp = time();
        $dest = $to->address;
        $headers['From'] = $from->toString();
        $headers['To'] = $to->toString();
        if ($replyto) {
            $headers['Reply-To'] = $replyto;
        } else {
            $headers['Reply-To'] = $from->toString();
        }
        $headers['Subject'] = wfQuotedPrintable($subject);
        $headers['Date'] = date('r');
        $headers['MIME-Version'] = '1.0';
        $headers['Content-type'] = 'text/plain; charset=' . $wgOutputEncoding;
        $headers['Content-transfer-encoding'] = '8bit';
        $headers['Message-ID'] = "<{$timestamp}" . $wgUser->getName() . '@' . $wgSMTP['IDHost'] . '>';
        // FIXME
        $headers['X-Mailer'] = 'MediaWiki mailer';
        // Create the mail object using the Mail::factory method
        $mail_object =& Mail::factory('smtp', $wgSMTP);
        wfDebug("Sending mail via PEAR::Mail to {$dest}\n");
        $mailResult =& $mail_object->send($dest, $headers, $body);
        # Based on the result return an error string,
        if ($mailResult === true) {
            return '';
        } elseif (is_object($mailResult)) {
            wfDebug("PEAR::Mail failed: " . $mailResult->getMessage() . "\n");
            return $mailResult->getMessage();
        } else {
            wfDebug("PEAR::Mail failed, unknown error result\n");
            return 'Mail object return unknown error.';
        }
    } else {
        # In the following $headers = expression we removed "Reply-To: {$from}\r\n" , because it is treated differently
        # (fifth parameter of the PHP mail function, see some lines below)
        $headers = "MIME-Version: 1.0\n" . "Content-type: text/plain; charset={$wgOutputEncoding}\n" . "Content-Transfer-Encoding: 8bit\n" . "X-Mailer: MediaWiki mailer\n" . "From: {$from->toString()}\n";
        if ($replyto) {
            $headers .= "Reply-To: {$replyto}\n";
        } else {
            $headers .= 'Reply-To: ' . $from->toString() . "\n";
        }
        $dest = $to->toString();
        $wgErrorString = '';
        set_error_handler('mailErrorHandler');
        wfDebug("Sending mail via internal mail() function to {$dest}\n");
        mail($dest, wfQuotedPrintable($subject), $body, $headers);
        restore_error_handler();
        if ($wgErrorString) {
            wfDebug("Error sending mail: {$wgErrorString}\n");
        }
        return $wgErrorString;
    }
}
 function doSubmit()
 {
     global $wgOut, $wgRequest;
     global $wgUserEmailUseReplyTo, $wgEmergencyContact;
     global $wgContactSender, $wgContactSenderName;
     $csender = $wgContactSender ? $wgContactSender : $wgEmergencyContact;
     $cname = $wgContactSenderName;
     $fname = 'EmailContactForm::doSubmit';
     wfDebug("{$fname}: start\n");
     $to = new MailAddress($this->target);
     $replyto = null;
     if (!$this->fromaddress) {
         $from = new MailAddress($csender, $cname);
     } elseif ($wgUserEmailUseReplyTo) {
         $from = new MailAddress($csender, $cname);
         $replyto = new MailAddress($this->fromaddress, $this->fromname);
     } else {
         $from = new MailAddress($this->fromaddress, $this->fromname);
     }
     $subject = trim($this->subject);
     if ($subject === "") {
         $subject = wfMsgForContent("contactpage-defsubject");
     }
     if ($this->fromname !== "") {
         $subject = wfMsgForContent("contactpage-subject-and-sender", $subject, $this->fromname);
     } elseif ($this->fromaddress !== "") {
         $subject = wfMsgForContent("contactpage-subject-and-sender", $subject, $this->fromaddress);
     }
     if (wfRunHooks('ContactForm', array(&$to, &$replyto, &$subject, &$this->text))) {
         wfDebug("{$fname}: sending mail from " . $from->toString() . " to " . $to->toString() . " replyto " . ($replyto == null ? '-/-' : $replyto->toString()) . "\n");
         $replyaddr = $replyto == null ? null : $replyto;
         $mailResult = UserMailer::send($to, $from, $subject, $this->text, $replyaddr);
         if (WikiError::isError($mailResult)) {
             $wgOut->addWikiText(wfMsg("usermailererror") . $mailResult->getMessage());
         } else {
             // if the user requested a copy of this mail, do this now,
             // unless they are emailing themselves, in which case one copy of the message is sufficient.
             if ($this->cc_me && $replyto) {
                 $cc_subject = wfMsg('emailccsubject', $this->target->getName(), $subject);
                 if (wfRunHooks('ContactForm', array(&$from, &$replyto, &$cc_subject, &$this->text))) {
                     wfDebug("{$fname}: sending cc mail from " . $from->toString() . " to " . $replyto->toString() . "\n");
                     $ccResult = UserMailer::send($replyto, $from, $cc_subject, $this->text);
                     if (WikiError::isError($ccResult)) {
                         // At this stage, the user's CC mail has failed, but their
                         // original mail has succeeded. It's unlikely, but still, what to do?
                         // We can either show them an error, or we can say everything was fine,
                         // or we can say we sort of failed AND sort of succeeded. Of these options,
                         // simply saying there was an error is probably best.
                         $wgOut->addWikiText(wfMsg("usermailererror") . $ccResult);
                         return;
                     }
                 }
             }
             wfDebug("{$fname}: success\n");
             $returnto = Title::newFromText($wgRequest->getVal('returnto'));
             if (is_null($returnto) || !$returnto->isLocal()) {
                 $returnto = SpecialPage::getTitleFor("Contact");
             }
             $wgOut->redirect($returnto->getFullUrl());
             wfRunHooks('ContactFromComplete', array($to, $replyto, $subject, $this->text));
         }
     }
     wfDebug("{$fname}: end\n");
 }
Example #13
0
 public function addBcc($bcc, $bccName = '')
 {
     if (!$this->isValidMail($bcc)) {
         throw new \Core3\Exception\InvalidArgument();
     }
     $adr = new MailAddress();
     $adr->setAddress($bcc);
     $adr->setName($bccName);
     $this->mailBcc[] = $adr;
 }
 /**
  * This function will perform a direct (authenticated) login to
  * a SMTP Server to use for mail relaying if 'wgSMTP' specifies an
  * array of parameters. It requires PEAR:Mail to do that.
  * Otherwise it just uses the standard PHP 'mail' function.
  *
  * @param MailAddress|MailAddress[] $to Recipient's email (or an array of them)
  * @param MailAddress $from Sender's email
  * @param string $subject Email's subject.
  * @param string $body Email's text or Array of two strings to be the text and html bodies
  * @param MailAddress $replyto Optional reply-to email (default: null).
  * @param string $contentType Optional custom Content-Type (default: text/plain; charset=UTF-8)
  * @throws MWException
  * @throws Exception
  * @return Status
  */
 public static function send($to, $from, $subject, $body, $replyto = null, $contentType = 'text/plain; charset=UTF-8')
 {
     global $wgSMTP, $wgEnotifMaxRecips, $wgAdditionalMailParams, $wgAllowHTMLEmail;
     $mime = null;
     if (!is_array($to)) {
         $to = array($to);
     }
     // mail body must have some content
     $minBodyLen = 10;
     // arbitrary but longer than Array or Object to detect casting error
     // body must either be a string or an array with text and body
     if (!(!is_array($body) && strlen($body) >= $minBodyLen) && !(is_array($body) && isset($body['text']) && isset($body['html']) && strlen($body['text']) >= $minBodyLen && strlen($body['html']) >= $minBodyLen)) {
         // if it is neither we have a problem
         return Status::newFatal('user-mail-no-body');
     }
     if (!$wgAllowHTMLEmail && is_array($body)) {
         // HTML not wanted.  Dump it.
         $body = $body['text'];
     }
     wfDebug(__METHOD__ . ': sending mail to ' . implode(', ', $to) . "\n");
     # Make sure we have at least one address
     $has_address = false;
     foreach ($to as $u) {
         if ($u->address) {
             $has_address = true;
             break;
         }
     }
     if (!$has_address) {
         return Status::newFatal('user-mail-no-addy');
     }
     # Forge email headers
     # -------------------
     #
     # WARNING
     #
     # DO NOT add To: or Subject: headers at this step. They need to be
     # handled differently depending upon the mailer we are going to use.
     #
     # To:
     #  PHP mail() first argument is the mail receiver. The argument is
     #  used as a recipient destination and as a To header.
     #
     #  PEAR mailer has a recipient argument which is only used to
     #  send the mail. If no To header is given, PEAR will set it to
     #  to 'undisclosed-recipients:'.
     #
     #  NOTE: To: is for presentation, the actual recipient is specified
     #  by the mailer using the Rcpt-To: header.
     #
     # Subject:
     #  PHP mail() second argument to pass the subject, passing a Subject
     #  as an additional header will result in a duplicate header.
     #
     #  PEAR mailer should be passed a Subject header.
     #
     # -- hashar 20120218
     $headers['From'] = $from->toString();
     $returnPath = $from->address;
     $extraParams = $wgAdditionalMailParams;
     // Hook to generate custom VERP address for 'Return-Path'
     Hooks::run('UserMailerChangeReturnPath', array($to, &$returnPath));
     # Add the envelope sender address using the -f command line option when PHP mail() is used.
     # Will default to the $from->address when the UserMailerChangeReturnPath hook fails and the
     # generated VERP address when the hook runs effectively.
     $extraParams .= ' -f ' . $returnPath;
     $headers['Return-Path'] = $returnPath;
     if ($replyto) {
         $headers['Reply-To'] = $replyto->toString();
     }
     $headers['Date'] = MWTimestamp::getLocalInstance()->format('r');
     $headers['Message-ID'] = self::makeMsgId();
     $headers['X-Mailer'] = 'MediaWiki mailer';
     # Line endings need to be different on Unix and Windows due to
     # the bug described at http://trac.wordpress.org/ticket/2603
     if (wfIsWindows()) {
         $endl = "\r\n";
     } else {
         $endl = "\n";
     }
     if (is_array($body)) {
         // we are sending a multipart message
         wfDebug("Assembling multipart mime email\n");
         if (!stream_resolve_include_path('Mail/mime.php')) {
             wfDebug("PEAR Mail_Mime package is not installed. Falling back to text email.\n");
             // remove the html body for text email fall back
             $body = $body['text'];
         } else {
             require_once 'Mail/mime.php';
             if (wfIsWindows()) {
                 $body['text'] = str_replace("\n", "\r\n", $body['text']);
                 $body['html'] = str_replace("\n", "\r\n", $body['html']);
             }
             $mime = new Mail_mime(array('eol' => $endl, 'text_charset' => 'UTF-8', 'html_charset' => 'UTF-8'));
             $mime->setTXTBody($body['text']);
             $mime->setHTMLBody($body['html']);
             $body = $mime->get();
             // must call get() before headers()
             $headers = $mime->headers($headers);
         }
     }
     if ($mime === null) {
         // sending text only, either deliberately or as a fallback
         if (wfIsWindows()) {
             $body = str_replace("\n", "\r\n", $body);
         }
         $headers['MIME-Version'] = '1.0';
         $headers['Content-type'] = is_null($contentType) ? 'text/plain; charset=UTF-8' : $contentType;
         $headers['Content-transfer-encoding'] = '8bit';
     }
     $ret = Hooks::run('AlternateUserMailer', array($headers, $to, $from, $subject, $body));
     if ($ret === false) {
         // the hook implementation will return false to skip regular mail sending
         return Status::newGood();
     } elseif ($ret !== true) {
         // the hook implementation will return a string to pass an error message
         return Status::newFatal('php-mail-error', $ret);
     }
     if (is_array($wgSMTP)) {
         #
         # PEAR MAILER
         #
         //start Eli Agbayani Nov 26, 2015
         $path = '/usr/local/Cellar/php53/5.3.29_2/lib/php';
         set_include_path(get_include_path() . PATH_SEPARATOR . $path);
         //end Eli Agbayani
         if (!stream_resolve_include_path('Mail.php')) {
             throw new MWException('PEAR mail package is not installed');
         }
         require_once 'Mail.php';
         wfSuppressWarnings();
         // Create the mail object using the Mail::factory method
         $mail_object =& Mail::factory('smtp', $wgSMTP);
         if (PEAR::isError($mail_object)) {
             wfDebug("PEAR::Mail factory failed: " . $mail_object->getMessage() . "\n");
             wfRestoreWarnings();
             return Status::newFatal('pear-mail-error', $mail_object->getMessage());
         }
         wfDebug("Sending mail via PEAR::Mail\n");
         $headers['Subject'] = self::quotedPrintable($subject);
         # When sending only to one recipient, shows it its email using To:
         if (count($to) == 1) {
             $headers['To'] = $to[0]->toString();
         }
         # Split jobs since SMTP servers tends to limit the maximum
         # number of possible recipients.
         $chunks = array_chunk($to, $wgEnotifMaxRecips);
         foreach ($chunks as $chunk) {
             $status = self::sendWithPear($mail_object, $chunk, $headers, $body);
             # FIXME : some chunks might be sent while others are not!
             if (!$status->isOK()) {
                 wfRestoreWarnings();
                 return $status;
             }
         }
         wfRestoreWarnings();
         return Status::newGood();
     } else {
         #
         # PHP mail()
         #
         if (count($to) > 1) {
             $headers['To'] = 'undisclosed-recipients:;';
         }
         $headers = self::arrayToHeaderString($headers, $endl);
         wfDebug("Sending mail via internal mail() function\n");
         self::$mErrorString = '';
         $html_errors = ini_get('html_errors');
         ini_set('html_errors', '0');
         set_error_handler('UserMailer::errorHandler');
         try {
             $safeMode = wfIniGetBool('safe_mode');
             foreach ($to as $recip) {
                 if ($safeMode) {
                     $sent = mail($recip, self::quotedPrintable($subject), $body, $headers);
                 } else {
                     $sent = mail($recip, self::quotedPrintable($subject), $body, $headers, $extraParams);
                 }
             }
         } catch (Exception $e) {
             restore_error_handler();
             throw $e;
         }
         restore_error_handler();
         ini_set('html_errors', $html_errors);
         if (self::$mErrorString) {
             wfDebug("Error sending mail: " . self::$mErrorString . "\n");
             return Status::newFatal('php-mail-error', self::$mErrorString);
         } elseif (!$sent) {
             // mail function only tells if there's an error
             wfDebug("Unknown error sending mail\n");
             return Status::newFatal('php-mail-error-unknown');
         } else {
             return Status::newGood();
         }
     }
 }
 /**
  * @covers MailAddress::__toString
  */
 public function test__ToString()
 {
     $ma = new MailAddress('some@email.com', 'UserName', 'A real name');
     $this->assertEquals($ma->toString(), (string) $ma);
 }
 protected function doResolveRequest($approved, $data)
 {
     $request = GlobalRenameRequest::newFromId($data['rid']);
     $oldUser = User::newFromName($request->getName());
     if ($request->userIsGlobal() || $request->getWiki() === wfWikiId()) {
         $notifyEmail = MailAddress::newFromUser($oldUser);
     } else {
         $notifyEmail = $this->getRemoteUserMailAddress($request->getWiki(), $request->getName());
     }
     $newUser = User::newFromName($request->getNewName(), 'creatable');
     $status = new Status();
     $session = $this->getContext()->exportSession();
     if ($approved) {
         if ($request->userIsGlobal()) {
             // Trigger a global rename job
             $globalRenameUser = new GlobalRenameUser($this->getUser(), $oldUser, CentralAuthUser::getInstance($oldUser), $newUser, CentralAuthUser::getInstance($newUser), new GlobalRenameUserStatus($newUser->getName()), 'JobQueueGroup::singleton', new GlobalRenameUserDatabaseUpdates(), new GlobalRenameUserLogger($this->getUser()), $session);
             $status = $globalRenameUser->rename($data);
         } else {
             // If the user is local-only:
             // * rename the local user using LocalRenameUserJob
             // * create a global user attached only to the local wiki
             $job = new LocalRenameUserJob(Title::newFromText('Global rename job'), array('from' => $oldUser->getName(), 'to' => $newUser->getName(), 'renamer' => $this->getUser()->getName(), 'movepages' => true, 'suppressredirects' => true, 'promotetoglobal' => true, 'reason' => $data['reason'], 'session' => $session));
             JobQueueGroup::singleton($request->getWiki())->push($job);
             // Now log it
             $this->logPromotionRename($oldUser->getName(), $request->getWiki(), $newUser->getName(), $data['reason']);
             $status = Status::newGood();
         }
     }
     if ($status->isGood()) {
         $request->setStatus($approved ? GlobalRenameRequest::APPROVED : GlobalRenameRequest::REJECTED);
         $request->setCompleted(wfTimestampNow());
         $request->setPerformer(CentralAuthUser::getInstance($this->getUser())->getId());
         $request->setComments($data['comments']);
         if ($request->save()) {
             // Send email to the user about the change in status.
             if ($approved) {
                 $subject = $this->msg('globalrenamequeue-email-subject-approved')->inContentLanguage()->text();
                 $body = $this->msg('globalrenamequeue-email-body-approved', array($oldUser->getName(), $newUser->getName()))->inContentLanguage()->text();
             } else {
                 $subject = $this->msg('globalrenamequeue-email-subject-rejected')->inContentLanguage()->text();
                 $body = $this->msg('globalrenamequeue-email-body-rejected', array($oldUser->getName(), $newUser->getName(), $request->getComments()))->inContentLanguage()->text();
             }
             if ($notifyEmail !== null && $notifyEmail->address) {
                 $type = $approved ? 'approval' : 'rejection';
                 wfDebugLog('CentralAuthRename', "Sending {$type} email to User:{$oldUser->getName()}/{$notifyEmail->address}");
                 $this->sendNotificationEmail($notifyEmail, $subject, $body);
             }
         } else {
             $status->fatal('globalrenamequeue-request-savefailed');
         }
     }
     return $status;
 }
function wfTodoParserFunction_Render( &$parser, $input, $users, $project='') {
    global $wgOut, $wgSitename, $wgEmergencyContact, $todoPreview;
    global $wgUseProjects;

    $username = '';
    $fullname = '';
    $u = 0;
    $userIdList = array();
    $userIdList2 = array();
    $dbr = wfGetDB( DB_SLAVE );

    $task_text = '';
    $task_project = '';

    if ($wgUseProjects) {
        if (isset($project) && ($project != '')) {
            $task_project .= "''";
            $first = true;
            $validProjects = getValidProjects();
            $projlist = preg_split('/\s*,\s*/', $project, -1, PREG_SPLIT_NO_EMPTY);
            foreach ( $projlist as $proj ) {
                if (!$first) {
                    $task_project .= ', ';
                } else {
                    $first = false;
                }
                $task_project .= validateProject($validProjects, $proj);
            }
            $task_project .= "'' - ";
        }
    }

    $task_text .= "$input (''' ";

    if ($users == '') {                                  // if no user specified
        $task_text .= wfMsgTL('tasklistunspecuser');
    } else {
        $first = true;
        $userlist = preg_split('/\s*,\s*/', $users, -1, PREG_SPLIT_NO_EMPTY);
        foreach ( $userlist as $user ) {
            if (!$first) {
                $task_text .= ', ';
            } else {
                $first = false;
            }
            $userid = getUserIDFromUserText($user);
            if ($userid != 0) {                         // successfully found the user
                $u = User::newFromId($userid);
                $username = $u->getName();
                $fullname = $u->getRealName();
                if ($fullname == '')
                    $task_text .= $username;
                else
                    $task_text .= $fullname;
                array_push($userIdList, $userid);
                array_push($userIdList2, $userid);
            } else {                                    // fall through to worst case scenario
                $task_text .= wfMsgTL('tasklistincorrectuser');
            }
        }
    }
    $task_text .= "''' )";
    $text = $task_project . $task_text;

    /* The following assumes the existance of an extra wiki table called $prefix_todo.
       To create this table issue
          CREATE TABLE wiki_todo (
               id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
               hash TINYBLOB
          );
     */

    $hash = md5($task_text);
    if (is_object($todoPreview) && !$todoPreview->preview) {
        /* Only when the action is a Submit instead of a Preview, send out an email
           reminder and store in database (if needed).
         */
        $adminAddress = new MailAddress( $wgEmergencyContact, 'WikiAdmin' );
        $tasklist = Title::newFromText("Special:TaskList");
        $body = sprintf(wfMsgTL('tasklistemailbody'), $parser->getTitle()->getFullURL(), $tasklist->getFullURL(), $wgSitename);
        $row = $dbr->selectRow( 'todo', 'id', array( 'hash' => $hash ), __METHOD__ );
        if (!$row) {                                    // this is a new todo item
            while ($userid = array_pop($userIdList)) {
                $u = User::newFromId($userid);
                $fullname = $u->getRealName();
                $email = sprintf(wfMsgTL('tasklistemail'), $fullname . $body);
                $u->sendMail(sprintf(wfMsgTL('tasklistemailsubject'), $wgSitename), $email, $adminAddress->toString());
                $dbr->insert('todo', array( 'hash' => $hash ), __METHOD__ );
            }
        }
    }

    return $text;
}