Path: blob/master/src/applications/auth/data/PhabricatorAuthInviteAction.php
12256 views
<?php12final class PhabricatorAuthInviteAction extends Phobject {34private $rawInput;5private $emailAddress;6private $userPHID;7private $issues = array();8private $action;910const ACTION_SEND = 'invite.send';11const ACTION_ERROR = 'invite.error';12const ACTION_IGNORE = 'invite.ignore';1314const ISSUE_PARSE = 'invite.parse';15const ISSUE_DUPLICATE = 'invite.duplicate';16const ISSUE_UNVERIFIED = 'invite.unverified';17const ISSUE_VERIFIED = 'invite.verified';18const ISSUE_INVITED = 'invite.invited';19const ISSUE_ACCEPTED = 'invite.accepted';2021public function getRawInput() {22return $this->rawInput;23}2425public function getEmailAddress() {26return $this->emailAddress;27}2829public function getUserPHID() {30return $this->userPHID;31}3233public function getIssues() {34return $this->issues;35}3637public function setAction($action) {38$this->action = $action;39return $this;40}4142public function getAction() {43return $this->action;44}4546public function willSend() {47return ($this->action == self::ACTION_SEND);48}4950public function getShortNameForIssue($issue) {51$map = array(52self::ISSUE_PARSE => pht('Not a Valid Email Address'),53self::ISSUE_DUPLICATE => pht('Address Duplicated in Input'),54self::ISSUE_UNVERIFIED => pht('Unverified User Email'),55self::ISSUE_VERIFIED => pht('Verified User Email'),56self::ISSUE_INVITED => pht('Previously Invited'),57self::ISSUE_ACCEPTED => pht('Already Accepted Invite'),58);5960return idx($map, $issue);61}6263public function getShortNameForAction($action) {64$map = array(65self::ACTION_SEND => pht('Will Send Invite'),66self::ACTION_ERROR => pht('Address Error'),67self::ACTION_IGNORE => pht('Will Ignore Address'),68);6970return idx($map, $action);71}7273public function getIconForAction($action) {74switch ($action) {75case self::ACTION_SEND:76$icon = 'fa-envelope-o';77$color = 'green';78break;79case self::ACTION_IGNORE:80$icon = 'fa-ban';81$color = 'grey';82break;83case self::ACTION_ERROR:84$icon = 'fa-exclamation-triangle';85$color = 'red';86break;87}8889return id(new PHUIIconView())90->setIcon("{$icon} {$color}");91}9293public static function newActionListFromAddresses(94PhabricatorUser $viewer,95array $addresses) {9697$results = array();98foreach ($addresses as $address) {99$result = new PhabricatorAuthInviteAction();100$result->rawInput = $address;101102$email = new PhutilEmailAddress($address);103$result->emailAddress = phutil_utf8_strtolower($email->getAddress());104105if (!preg_match('/^\S+@\S+\.\S+\z/', $result->emailAddress)) {106$result->issues[] = self::ISSUE_PARSE;107}108109$results[] = $result;110}111112// Identify duplicates.113$address_groups = mgroup($results, 'getEmailAddress');114foreach ($address_groups as $address => $group) {115if (count($group) > 1) {116foreach ($group as $action) {117$action->issues[] = self::ISSUE_DUPLICATE;118}119}120}121122// Identify addresses which are already in the system.123$addresses = mpull($results, 'getEmailAddress');124$email_objects = id(new PhabricatorUserEmail())->loadAllWhere(125'address IN (%Ls)',126$addresses);127128$email_map = array();129foreach ($email_objects as $email_object) {130$address_key = phutil_utf8_strtolower($email_object->getAddress());131$email_map[$address_key] = $email_object;132}133134// Identify outstanding invites.135$invites = id(new PhabricatorAuthInviteQuery())136->setViewer($viewer)137->withEmailAddresses($addresses)138->execute();139$invite_map = mpull($invites, null, 'getEmailAddress');140141foreach ($results as $action) {142$email = idx($email_map, $action->getEmailAddress());143if ($email) {144if ($email->getUserPHID()) {145$action->userPHID = $email->getUserPHID();146if ($email->getIsVerified()) {147$action->issues[] = self::ISSUE_VERIFIED;148} else {149$action->issues[] = self::ISSUE_UNVERIFIED;150}151}152}153154$invite = idx($invite_map, $action->getEmailAddress());155if ($invite) {156if ($invite->getAcceptedByPHID()) {157$action->issues[] = self::ISSUE_ACCEPTED;158if (!$action->userPHID) {159// This could be different from the user who is currently attached160// to the email address if the address was removed or added to a161// different account later. Only show it if the address was162// removed, since the current status is more up-to-date otherwise.163$action->userPHID = $invite->getAcceptedByPHID();164}165} else {166$action->issues[] = self::ISSUE_INVITED;167}168}169}170171foreach ($results as $result) {172foreach ($result->getIssues() as $issue) {173switch ($issue) {174case self::ISSUE_PARSE:175$result->action = self::ACTION_ERROR;176break;177case self::ISSUE_ACCEPTED:178case self::ISSUE_VERIFIED:179$result->action = self::ACTION_IGNORE;180break;181}182}183if (!$result->action) {184$result->action = self::ACTION_SEND;185}186}187188return $results;189}190191public function sendInvite(PhabricatorUser $actor, $template) {192if (!$this->willSend()) {193throw new Exception(pht('Invite action is not a send action!'));194}195196if (!preg_match('/{\$INVITE_URI}/', $template)) {197throw new Exception(pht('Invite template does not include invite URI!'));198}199200PhabricatorWorker::scheduleTask(201'PhabricatorAuthInviteWorker',202array(203'address' => $this->getEmailAddress(),204'template' => $template,205'authorPHID' => $actor->getPHID(),206));207}208209}210211212