rawInput; } public function getEmailAddress() { return $this->emailAddress; } public function getUserPHID() { return $this->userPHID; } public function getIssues() { return $this->issues; } public function setAction($action) { $this->action = $action; return $this; } public function getAction() { return $this->action; } public function willSend() { return ($this->action == self::ACTION_SEND); } public function getShortNameForIssue($issue) { $map = array( self::ISSUE_PARSE => pht('Not a Valid Email Address'), self::ISSUE_DUPLICATE => pht('Address Duplicated in Input'), self::ISSUE_UNVERIFIED => pht('Unverified User Email'), self::ISSUE_VERIFIED => pht('Verified User Email'), self::ISSUE_INVITED => pht('Previously Invited'), self::ISSUE_ACCEPTED => pht('Already Accepted Invite'), ); return idx($map, $issue); } public function getShortNameForAction($action) { $map = array( self::ACTION_SEND => pht('Will Send Invite'), self::ACTION_ERROR => pht('Address Error'), self::ACTION_IGNORE => pht('Will Ignore Address'), ); return idx($map, $action); } public function getIconForAction($action) { switch ($action) { case self::ACTION_SEND: $icon = 'fa-envelope-o'; $color = 'green'; break; case self::ACTION_IGNORE: $icon = 'fa-ban'; $color = 'grey'; break; case self::ACTION_ERROR: $icon = 'fa-exclamation-triangle'; $color = 'red'; break; } return id(new PHUIIconView()) ->setIcon("{$icon} {$color}"); } public static function newActionListFromAddresses( PhabricatorUser $viewer, array $addresses) { $results = array(); foreach ($addresses as $address) { $result = new PhabricatorAuthInviteAction(); $result->rawInput = $address; $email = new PhutilEmailAddress($address); $result->emailAddress = phutil_utf8_strtolower($email->getAddress()); if (!preg_match('/^\S+@\S+\.\S+\z/', $result->emailAddress)) { $result->issues[] = self::ISSUE_PARSE; } $results[] = $result; } // Identify duplicates. $address_groups = mgroup($results, 'getEmailAddress'); foreach ($address_groups as $address => $group) { if (count($group) > 1) { foreach ($group as $action) { $action->issues[] = self::ISSUE_DUPLICATE; } } } // Identify addresses which are already in the system. $addresses = mpull($results, 'getEmailAddress'); $email_objects = id(new PhabricatorUserEmail())->loadAllWhere( 'address IN (%Ls)', $addresses); $email_map = array(); foreach ($email_objects as $email_object) { $address_key = phutil_utf8_strtolower($email_object->getAddress()); $email_map[$address_key] = $email_object; } // Identify outstanding invites. $invites = id(new PhabricatorAuthInviteQuery()) ->setViewer($viewer) ->withEmailAddresses($addresses) ->execute(); $invite_map = mpull($invites, null, 'getEmailAddress'); foreach ($results as $action) { $email = idx($email_map, $action->getEmailAddress()); if ($email) { if ($email->getUserPHID()) { $action->userPHID = $email->getUserPHID(); if ($email->getIsVerified()) { $action->issues[] = self::ISSUE_VERIFIED; } else { $action->issues[] = self::ISSUE_UNVERIFIED; } } } $invite = idx($invite_map, $action->getEmailAddress()); if ($invite) { if ($invite->getAcceptedByPHID()) { $action->issues[] = self::ISSUE_ACCEPTED; if (!$action->userPHID) { // This could be different from the user who is currently attached // to the email address if the address was removed or added to a // different account later. Only show it if the address was // removed, since the current status is more up-to-date otherwise. $action->userPHID = $invite->getAcceptedByPHID(); } } else { $action->issues[] = self::ISSUE_INVITED; } } } foreach ($results as $result) { foreach ($result->getIssues() as $issue) { switch ($issue) { case self::ISSUE_PARSE: $result->action = self::ACTION_ERROR; break; case self::ISSUE_ACCEPTED: case self::ISSUE_VERIFIED: $result->action = self::ACTION_IGNORE; break; } } if (!$result->action) { $result->action = self::ACTION_SEND; } } return $results; } public function sendInvite(PhabricatorUser $actor, $template) { if (!$this->willSend()) { throw new Exception(pht('Invite action is not a send action!')); } if (!preg_match('/{\$INVITE_URI}/', $template)) { throw new Exception(pht('Invite template does not include invite URI!')); } PhabricatorWorker::scheduleTask( 'PhabricatorAuthInviteWorker', array( 'address' => $this->getEmailAddress(), 'template' => $template, 'authorPHID' => $actor->getPHID(), )); } }