If users are on the email to Phabricator, do not send them the Phabricator reply.

Summary: When we receive an email, figure out if any of the other tos and ccs are users. If they are, pass their phids through the stach as "exclude phids" and exclude them from getting the email.

Test Plan: used the various applications (audit, differential, maniphest) and noted emails were sent as expected.

Reviewers: epriestley, vrana

Reviewed By: vrana

CC: aran, Korvin, vrana

Maniphest Tasks: T1676

Differential Revision: https://secure.phabricator.com/D3645
This commit is contained in:
Bob Trahan
2012-10-10 10:18:23 -07:00
parent b605878792
commit d9c6e07f2c
58 changed files with 302 additions and 292 deletions

View File

@@ -668,6 +668,7 @@ phutil_register_library_map(array(
'PhabricatorEdgeGraph' => 'infrastructure/edges/util/PhabricatorEdgeGraph.php', 'PhabricatorEdgeGraph' => 'infrastructure/edges/util/PhabricatorEdgeGraph.php',
'PhabricatorEdgeQuery' => 'infrastructure/edges/query/PhabricatorEdgeQuery.php', 'PhabricatorEdgeQuery' => 'infrastructure/edges/query/PhabricatorEdgeQuery.php',
'PhabricatorEdgeTestCase' => 'infrastructure/edges/__tests__/PhabricatorEdgeTestCase.php', 'PhabricatorEdgeTestCase' => 'infrastructure/edges/__tests__/PhabricatorEdgeTestCase.php',
'PhabricatorEditor' => 'infrastructure/PhabricatorEditor.php',
'PhabricatorEmailLoginController' => 'applications/auth/controller/PhabricatorEmailLoginController.php', 'PhabricatorEmailLoginController' => 'applications/auth/controller/PhabricatorEmailLoginController.php',
'PhabricatorEmailTokenController' => 'applications/auth/controller/PhabricatorEmailTokenController.php', 'PhabricatorEmailTokenController' => 'applications/auth/controller/PhabricatorEmailTokenController.php',
'PhabricatorEmailVerificationController' => 'applications/people/controller/PhabricatorEmailVerificationController.php', 'PhabricatorEmailVerificationController' => 'applications/people/controller/PhabricatorEmailVerificationController.php',
@@ -1450,6 +1451,7 @@ phutil_register_library_map(array(
'DifferentialChangesetParserTestCase' => 'ArcanistPhutilTestCase', 'DifferentialChangesetParserTestCase' => 'ArcanistPhutilTestCase',
'DifferentialChangesetViewController' => 'DifferentialController', 'DifferentialChangesetViewController' => 'DifferentialController',
'DifferentialComment' => 'DifferentialDAO', 'DifferentialComment' => 'DifferentialDAO',
'DifferentialCommentEditor' => 'PhabricatorEditor',
'DifferentialCommentMail' => 'DifferentialMail', 'DifferentialCommentMail' => 'DifferentialMail',
'DifferentialCommentPreviewController' => 'DifferentialController', 'DifferentialCommentPreviewController' => 'DifferentialController',
'DifferentialCommentSaveController' => 'DifferentialController', 'DifferentialCommentSaveController' => 'DifferentialController',
@@ -1507,6 +1509,7 @@ phutil_register_library_map(array(
'DifferentialRevisionCommentView' => 'AphrontView', 'DifferentialRevisionCommentView' => 'AphrontView',
'DifferentialRevisionDetailView' => 'AphrontView', 'DifferentialRevisionDetailView' => 'AphrontView',
'DifferentialRevisionEditController' => 'DifferentialController', 'DifferentialRevisionEditController' => 'DifferentialController',
'DifferentialRevisionEditor' => 'PhabricatorEditor',
'DifferentialRevisionIDFieldParserTestCase' => 'PhabricatorTestCase', 'DifferentialRevisionIDFieldParserTestCase' => 'PhabricatorTestCase',
'DifferentialRevisionIDFieldSpecification' => 'DifferentialFieldSpecification', 'DifferentialRevisionIDFieldSpecification' => 'DifferentialFieldSpecification',
'DifferentialRevisionListController' => 'DifferentialController', 'DifferentialRevisionListController' => 'DifferentialController',
@@ -1714,6 +1717,7 @@ phutil_register_library_map(array(
1 => 'PhabricatorMarkupInterface', 1 => 'PhabricatorMarkupInterface',
), ),
'ManiphestTransactionDetailView' => 'ManiphestView', 'ManiphestTransactionDetailView' => 'ManiphestView',
'ManiphestTransactionEditor' => 'PhabricatorEditor',
'ManiphestTransactionListView' => 'ManiphestView', 'ManiphestTransactionListView' => 'ManiphestView',
'ManiphestTransactionPreviewController' => 'ManiphestController', 'ManiphestTransactionPreviewController' => 'ManiphestController',
'ManiphestTransactionSaveController' => 'ManiphestController', 'ManiphestTransactionSaveController' => 'ManiphestController',
@@ -1765,6 +1769,7 @@ phutil_register_library_map(array(
'PhabricatorApplicationsListController' => 'PhabricatorController', 'PhabricatorApplicationsListController' => 'PhabricatorController',
'PhabricatorAuditAddCommentController' => 'PhabricatorAuditController', 'PhabricatorAuditAddCommentController' => 'PhabricatorAuditController',
'PhabricatorAuditComment' => 'PhabricatorAuditDAO', 'PhabricatorAuditComment' => 'PhabricatorAuditDAO',
'PhabricatorAuditCommentEditor' => 'PhabricatorEditor',
'PhabricatorAuditCommitListView' => 'AphrontView', 'PhabricatorAuditCommitListView' => 'AphrontView',
'PhabricatorAuditController' => 'PhabricatorController', 'PhabricatorAuditController' => 'PhabricatorController',
'PhabricatorAuditDAO' => 'PhabricatorLiskDAO', 'PhabricatorAuditDAO' => 'PhabricatorLiskDAO',
@@ -1839,6 +1844,7 @@ phutil_register_library_map(array(
'PhabricatorDraftDAO' => 'PhabricatorLiskDAO', 'PhabricatorDraftDAO' => 'PhabricatorLiskDAO',
'PhabricatorEdgeConfig' => 'PhabricatorEdgeConstants', 'PhabricatorEdgeConfig' => 'PhabricatorEdgeConstants',
'PhabricatorEdgeCycleException' => 'Exception', 'PhabricatorEdgeCycleException' => 'Exception',
'PhabricatorEdgeEditor' => 'PhabricatorEditor',
'PhabricatorEdgeGraph' => 'AbstractDirectedGraph', 'PhabricatorEdgeGraph' => 'AbstractDirectedGraph',
'PhabricatorEdgeQuery' => 'PhabricatorQuery', 'PhabricatorEdgeQuery' => 'PhabricatorQuery',
'PhabricatorEdgeTestCase' => 'PhabricatorTestCase', 'PhabricatorEdgeTestCase' => 'PhabricatorTestCase',
@@ -2083,6 +2089,7 @@ phutil_register_library_map(array(
'PhabricatorProjectController' => 'PhabricatorController', 'PhabricatorProjectController' => 'PhabricatorController',
'PhabricatorProjectCreateController' => 'PhabricatorProjectController', 'PhabricatorProjectCreateController' => 'PhabricatorProjectController',
'PhabricatorProjectDAO' => 'PhabricatorLiskDAO', 'PhabricatorProjectDAO' => 'PhabricatorLiskDAO',
'PhabricatorProjectEditor' => 'PhabricatorEditor',
'PhabricatorProjectEditorTestCase' => 'PhabricatorTestCase', 'PhabricatorProjectEditorTestCase' => 'PhabricatorTestCase',
'PhabricatorProjectListController' => 'PhabricatorProjectController', 'PhabricatorProjectListController' => 'PhabricatorProjectController',
'PhabricatorProjectMembersEditController' => 'PhabricatorProjectController', 'PhabricatorProjectMembersEditController' => 'PhabricatorProjectController',
@@ -2202,6 +2209,7 @@ phutil_register_library_map(array(
'PhabricatorStorageManagementWorkflow' => 'PhutilArgumentWorkflow', 'PhabricatorStorageManagementWorkflow' => 'PhutilArgumentWorkflow',
'PhabricatorSubscribersQuery' => 'PhabricatorQuery', 'PhabricatorSubscribersQuery' => 'PhabricatorQuery',
'PhabricatorSubscriptionsEditController' => 'PhabricatorController', 'PhabricatorSubscriptionsEditController' => 'PhabricatorController',
'PhabricatorSubscriptionsEditor' => 'PhabricatorEditor',
'PhabricatorSubscriptionsUIEventListener' => 'PhutilEventListener', 'PhabricatorSubscriptionsUIEventListener' => 'PhutilEventListener',
'PhabricatorSymbolNameLinter' => 'ArcanistXHPASTLintNamingHook', 'PhabricatorSymbolNameLinter' => 'ArcanistXHPASTLintNamingHook',
'PhabricatorTaskmasterDaemon' => 'PhabricatorDaemon', 'PhabricatorTaskmasterDaemon' => 'PhabricatorDaemon',
@@ -2229,6 +2237,7 @@ phutil_register_library_map(array(
1 => 'PhutilPerson', 1 => 'PhutilPerson',
), ),
'PhabricatorUserDAO' => 'PhabricatorLiskDAO', 'PhabricatorUserDAO' => 'PhabricatorLiskDAO',
'PhabricatorUserEditor' => 'PhabricatorEditor',
'PhabricatorUserEmail' => 'PhabricatorUserDAO', 'PhabricatorUserEmail' => 'PhabricatorUserDAO',
'PhabricatorUserLDAPInfo' => 'PhabricatorUserDAO', 'PhabricatorUserLDAPInfo' => 'PhabricatorUserDAO',
'PhabricatorUserLog' => 'PhabricatorUserDAO', 'PhabricatorUserLog' => 'PhabricatorUserDAO',
@@ -2304,6 +2313,7 @@ phutil_register_library_map(array(
'PhrictionDiffController' => 'PhrictionController', 'PhrictionDiffController' => 'PhrictionController',
'PhrictionDocument' => 'PhrictionDAO', 'PhrictionDocument' => 'PhrictionDAO',
'PhrictionDocumentController' => 'PhrictionController', 'PhrictionDocumentController' => 'PhrictionController',
'PhrictionDocumentEditor' => 'PhabricatorEditor',
'PhrictionDocumentPreviewController' => 'PhrictionController', 'PhrictionDocumentPreviewController' => 'PhrictionController',
'PhrictionDocumentStatus' => 'PhrictionConstants', 'PhrictionDocumentStatus' => 'PhrictionConstants',
'PhrictionDocumentTestCase' => 'PhabricatorTestCase', 'PhrictionDocumentTestCase' => 'PhabricatorTestCase',
@@ -2318,6 +2328,7 @@ phutil_register_library_map(array(
1 => 'PhabricatorMarkupInterface', 1 => 'PhabricatorMarkupInterface',
2 => 'PonderVotableInterface', 2 => 'PonderVotableInterface',
), ),
'PonderAnswerEditor' => 'PhabricatorEditor',
'PonderAnswerListView' => 'AphrontView', 'PonderAnswerListView' => 'AphrontView',
'PonderAnswerPreviewController' => 'PonderController', 'PonderAnswerPreviewController' => 'PonderController',
'PonderAnswerQuery' => 'PhabricatorOffsetPagedQuery', 'PonderAnswerQuery' => 'PhabricatorOffsetPagedQuery',
@@ -2329,6 +2340,7 @@ phutil_register_library_map(array(
0 => 'PonderDAO', 0 => 'PonderDAO',
1 => 'PhabricatorMarkupInterface', 1 => 'PhabricatorMarkupInterface',
), ),
'PonderCommentEditor' => 'PhabricatorEditor',
'PonderCommentListView' => 'AphrontView', 'PonderCommentListView' => 'AphrontView',
'PonderCommentMail' => 'PonderMail', 'PonderCommentMail' => 'PonderMail',
'PonderCommentQuery' => 'PhabricatorQuery', 'PonderCommentQuery' => 'PhabricatorQuery',
@@ -2347,6 +2359,7 @@ phutil_register_library_map(array(
), ),
'PonderQuestionAskController' => 'PonderController', 'PonderQuestionAskController' => 'PonderController',
'PonderQuestionDetailView' => 'AphrontView', 'PonderQuestionDetailView' => 'AphrontView',
'PonderQuestionEditor' => 'PhabricatorEditor',
'PonderQuestionPreviewController' => 'PonderController', 'PonderQuestionPreviewController' => 'PonderController',
'PonderQuestionQuery' => 'PhabricatorOffsetPagedQuery', 'PonderQuestionQuery' => 'PhabricatorOffsetPagedQuery',
'PonderQuestionSummaryView' => 'AphrontView', 'PonderQuestionSummaryView' => 'AphrontView',
@@ -2355,6 +2368,7 @@ phutil_register_library_map(array(
'PonderRuleQuestion' => 'PhabricatorRemarkupRuleObjectName', 'PonderRuleQuestion' => 'PhabricatorRemarkupRuleObjectName',
'PonderUserProfileView' => 'AphrontView', 'PonderUserProfileView' => 'AphrontView',
'PonderVotableView' => 'AphrontView', 'PonderVotableView' => 'AphrontView',
'PonderVoteEditor' => 'PhabricatorEditor',
'PonderVoteSaveController' => 'PonderController', 'PonderVoteSaveController' => 'PonderController',
'QueryFormattingTestCase' => 'PhabricatorTestCase', 'QueryFormattingTestCase' => 'PhabricatorTestCase',
), ),

View File

@@ -61,7 +61,9 @@ final class PhabricatorAuditReplyHandler extends PhabricatorMailReplyHandler {
->setContent($mail->getCleanTextBody()); ->setContent($mail->getCleanTextBody());
$editor = new PhabricatorAuditCommentEditor($commit); $editor = new PhabricatorAuditCommentEditor($commit);
$editor->setUser($actor); $editor->setActor($actor);
$editor->setExcludeMailRecipientPHIDs(
$this->getExcludeMailRecipientPHIDs());
$editor->addComment($comment); $editor->addComment($comment);
} }

View File

@@ -61,7 +61,7 @@ final class PhabricatorAuditAddCommentController
} }
id(new PhabricatorAuditCommentEditor($commit)) id(new PhabricatorAuditCommentEditor($commit))
->setUser($user) ->setActor($user)
->setAttachInlineComments(true) ->setAttachInlineComments(true)
->addAuditors($auditors) ->addAuditors($auditors)
->addCCs($ccs) ->addCCs($ccs)

View File

@@ -16,10 +16,9 @@
* limitations under the License. * limitations under the License.
*/ */
final class PhabricatorAuditCommentEditor { final class PhabricatorAuditCommentEditor extends PhabricatorEditor {
private $commit; private $commit;
private $user;
private $attachInlineComments; private $attachInlineComments;
private $auditors = array(); private $auditors = array();
@@ -30,11 +29,6 @@ final class PhabricatorAuditCommentEditor {
return $this; return $this;
} }
public function setUser(PhabricatorUser $user) {
$this->user = $user;
return $this;
}
public function addAuditors(array $auditor_phids) { public function addAuditors(array $auditor_phids) {
$this->auditors = array_merge($this->auditors, $auditor_phids); $this->auditors = array_merge($this->auditors, $auditor_phids);
return $this; return $this;
@@ -53,7 +47,7 @@ final class PhabricatorAuditCommentEditor {
public function addComment(PhabricatorAuditComment $comment) { public function addComment(PhabricatorAuditComment $comment) {
$commit = $this->commit; $commit = $this->commit;
$user = $this->user; $actor = $this->getActor();
$other_comments = id(new PhabricatorAuditComment())->loadAllWhere( $other_comments = id(new PhabricatorAuditComment())->loadAllWhere(
'targetPHID = %s', 'targetPHID = %s',
@@ -64,12 +58,12 @@ final class PhabricatorAuditCommentEditor {
$inline_comments = id(new PhabricatorAuditInlineComment())->loadAllWhere( $inline_comments = id(new PhabricatorAuditInlineComment())->loadAllWhere(
'authorPHID = %s AND commitPHID = %s 'authorPHID = %s AND commitPHID = %s
AND auditCommentID IS NULL', AND auditCommentID IS NULL',
$user->getPHID(), $actor->getPHID(),
$commit->getPHID()); $commit->getPHID());
} }
$comment $comment
->setActorPHID($user->getPHID()) ->setActorPHID($actor->getPHID())
->setTargetPHID($commit->getPHID()) ->setTargetPHID($commit->getPHID())
->save(); ->save();
@@ -106,13 +100,13 @@ final class PhabricatorAuditCommentEditor {
$ccs = array_merge($ccs, $metacc); $ccs = array_merge($ccs, $metacc);
} }
// When a user submits an audit comment, we update all the audit requests // When an actor submits an audit comment, we update all the audit requests
// they have authority over to reflect the most recent status. The general // they have authority over to reflect the most recent status. The general
// idea here is that if audit has triggered for, e.g., several packages, but // idea here is that if audit has triggered for, e.g., several packages, but
// a user owns all of them, they can clear the audit requirement in one go // a user owns all of them, they can clear the audit requirement in one go
// without auditing the commit for each trigger. // without auditing the commit for each trigger.
$audit_phids = self::loadAuditPHIDsForUser($this->user); $audit_phids = self::loadAuditPHIDsForUser($actor);
$audit_phids = array_fill_keys($audit_phids, true); $audit_phids = array_fill_keys($audit_phids, true);
$requests = id(new PhabricatorRepositoryAuditRequest()) $requests = id(new PhabricatorRepositoryAuditRequest())
@@ -128,7 +122,7 @@ final class PhabricatorAuditCommentEditor {
// and handle the no-effect cases (e.g., closing and already-closed audit). // and handle the no-effect cases (e.g., closing and already-closed audit).
$user_is_author = ($user->getPHID() == $commit->getAuthorPHID()); $actor_is_author = ($actor->getPHID() == $commit->getAuthorPHID());
if ($action == PhabricatorAuditActionConstants::CLOSE) { if ($action == PhabricatorAuditActionConstants::CLOSE) {
// "Close" means wipe out all the concerns. // "Close" means wipe out all the concerns.
@@ -144,25 +138,25 @@ final class PhabricatorAuditCommentEditor {
// user row (never package/project rows), and always affects the user // user row (never package/project rows), and always affects the user
// row (other actions don't, if they were able to affect a package/project // row (other actions don't, if they were able to affect a package/project
// row). // row).
$user_request = null; $actor_request = null;
foreach ($requests as $request) { foreach ($requests as $request) {
if ($request->getAuditorPHID() == $user->getPHID()) { if ($request->getAuditorPHID() == $actor->getPHID()) {
$user_request = $request; $actor_request = $request;
break; break;
} }
} }
if (!$user_request) { if (!$actor_request) {
$user_request = id(new PhabricatorRepositoryAuditRequest()) $actor_request = id(new PhabricatorRepositoryAuditRequest())
->setCommitPHID($commit->getPHID()) ->setCommitPHID($commit->getPHID())
->setAuditorPHID($user->getPHID()) ->setAuditorPHID($actor->getPHID())
->setAuditReasons(array("Resigned")); ->setAuditReasons(array("Resigned"));
} }
$user_request $actor_request
->setAuditStatus(PhabricatorAuditStatusConstants::RESIGNED) ->setAuditStatus(PhabricatorAuditStatusConstants::RESIGNED)
->save(); ->save();
$requests[] = $user_request; $requests[] = $actor_request;
} else { } else {
$have_any_requests = false; $have_any_requests = false;
foreach ($requests as $request) { foreach ($requests as $request) {
@@ -170,7 +164,8 @@ final class PhabricatorAuditCommentEditor {
continue; continue;
} }
$request_is_for_user = ($request->getAuditorPHID() == $user->getPHID()); $request_is_for_actor =
($request->getAuditorPHID() == $actor->getPHID());
$have_any_requests = true; $have_any_requests = true;
$new_status = null; $new_status = null;
@@ -181,7 +176,7 @@ final class PhabricatorAuditCommentEditor {
// Commenting or adding cc's/auditors doesn't change status. // Commenting or adding cc's/auditors doesn't change status.
break; break;
case PhabricatorAuditActionConstants::ACCEPT: case PhabricatorAuditActionConstants::ACCEPT:
if (!$user_is_author || $request_is_for_user) { if (!$actor_is_author || $request_is_for_actor) {
// When modifying your own commits, you act only on behalf of // When modifying your own commits, you act only on behalf of
// yourself, not your packages/projects -- the idea being that // yourself, not your packages/projects -- the idea being that
// you can't accept your own commits. // you can't accept your own commits.
@@ -189,7 +184,7 @@ final class PhabricatorAuditCommentEditor {
} }
break; break;
case PhabricatorAuditActionConstants::CONCERN: case PhabricatorAuditActionConstants::CONCERN:
if (!$user_is_author || $request_is_for_user) { if (!$actor_is_author || $request_is_for_actor) {
// See above. // See above.
$new_status = PhabricatorAuditStatusConstants::CONCERNED; $new_status = PhabricatorAuditStatusConstants::CONCERNED;
} }
@@ -203,7 +198,7 @@ final class PhabricatorAuditCommentEditor {
} }
} }
// If the user has no current authority over any audit trigger, make a // If the actor has no current authority over any audit trigger, make a
// new one to represent their audit state. // new one to represent their audit state.
if (!$have_any_requests) { if (!$have_any_requests) {
$new_status = null; $new_status = null;
@@ -227,7 +222,7 @@ final class PhabricatorAuditCommentEditor {
$request = id(new PhabricatorRepositoryAuditRequest()) $request = id(new PhabricatorRepositoryAuditRequest())
->setCommitPHID($commit->getPHID()) ->setCommitPHID($commit->getPHID())
->setAuditorPHID($user->getPHID()) ->setAuditorPHID($actor->getPHID())
->setAuditStatus($new_status) ->setAuditStatus($new_status)
->setAuditReasons(array("Voluntary Participant")) ->setAuditReasons(array("Voluntary Participant"))
->save(); ->save();
@@ -270,7 +265,7 @@ final class PhabricatorAuditCommentEditor {
->setAuditorPHID($auditor_phid) ->setAuditorPHID($auditor_phid)
->setAuditStatus($audit_requested) ->setAuditStatus($audit_requested)
->setAuditReasons( ->setAuditReasons(
array('Added by ' . $user->getUsername())) array('Added by ' . $actor->getUsername()))
->save(); ->save();
} }
} }
@@ -283,7 +278,7 @@ final class PhabricatorAuditCommentEditor {
->setAuditorPHID($cc_phid) ->setAuditorPHID($cc_phid)
->setAuditStatus($audit_cc) ->setAuditStatus($audit_cc)
->setAuditReasons( ->setAuditReasons(
array('Added by ' . $user->getUsername())) array('Added by ' . $actor->getUsername()))
->save(); ->save();
} }
} }
@@ -322,13 +317,10 @@ final class PhabricatorAuditCommentEditor {
} }
// The user can audit on behalf of all projects they are a member of. // The user can audit on behalf of all projects they are a member of.
$query = new PhabricatorProjectQuery(); $projects = id(new PhabricatorProjectQuery())
->setViewer($user)
// TODO: As above. ->withMemberPHIDs(array($user->getPHID()))
$query->setViewer($user); ->execute();
$query->withMemberPHIDs(array($user->getPHID()));
$projects = $query->execute();
foreach ($projects as $project) { foreach ($projects as $project) {
$phids[$project->getPHID()] = true; $phids[$project->getPHID()] = true;
} }
@@ -341,18 +333,18 @@ final class PhabricatorAuditCommentEditor {
array $more_phids) { array $more_phids) {
$commit = $this->commit; $commit = $this->commit;
$user = $this->user; $actor = $this->getActor();
$related_phids = array_merge( $related_phids = array_merge(
array( array(
$user->getPHID(), $actor->getPHID(),
$commit->getPHID(), $commit->getPHID(),
), ),
$more_phids); $more_phids);
id(new PhabricatorFeedStoryPublisher()) id(new PhabricatorFeedStoryPublisher())
->setRelatedPHIDs($related_phids) ->setRelatedPHIDs($related_phids)
->setStoryAuthorPHID($user->getPHID()) ->setStoryAuthorPHID($actor->getPHID())
->setStoryTime(time()) ->setStoryTime(time())
->setStoryType(PhabricatorFeedStoryTypeConstants::STORY_AUDIT) ->setStoryType(PhabricatorFeedStoryTypeConstants::STORY_AUDIT)
->setStoryData( ->setStoryData(
@@ -445,6 +437,7 @@ final class PhabricatorAuditCommentEditor {
->setThreadID($thread_id, $is_new) ->setThreadID($thread_id, $is_new)
->addHeader('Thread-Topic', $thread_topic) ->addHeader('Thread-Topic', $thread_topic)
->setRelatedPHID($commit->getPHID()) ->setRelatedPHID($commit->getPHID())
->setExcludeMailRecipientPHIDs($this->getExcludeMailRecipientPHIDs())
->setIsBulk(true) ->setIsBulk(true)
->setBody($body); ->setBody($body);
@@ -484,8 +477,8 @@ final class PhabricatorAuditCommentEditor {
assert_instances_of($inline_comments, 'PhabricatorInlineCommentInterface'); assert_instances_of($inline_comments, 'PhabricatorInlineCommentInterface');
$commit = $this->commit; $commit = $this->commit;
$user = $this->user; $actor = $this->getActor();
$name = $user->getUsername(); $name = $actor->getUsername();
$verb = PhabricatorAuditActionConstants::getActionPastTenseVerb( $verb = PhabricatorAuditActionConstants::getActionPastTenseVerb(
$comment->getAction()); $comment->getAction());

View File

@@ -63,8 +63,8 @@ final class ConduitAPI_differential_close_Method
$editor = new DifferentialCommentEditor( $editor = new DifferentialCommentEditor(
$revision, $revision,
$request->getUser()->getPHID(),
DifferentialAction::ACTION_CLOSE); DifferentialAction::ACTION_CLOSE);
$editor->setActor($request->getUser());
$editor->save(); $editor->save();
$revision->setStatus(ArcanistDifferentialRevisionStatus::CLOSED); $revision->setStatus(ArcanistDifferentialRevisionStatus::CLOSED);

View File

@@ -63,8 +63,8 @@ final class ConduitAPI_differential_createcomment_Method
$editor = new DifferentialCommentEditor( $editor = new DifferentialCommentEditor(
$revision, $revision,
$request->getUser()->getPHID(),
$action); $action);
$editor->setActor($request->getUser());
$editor->setContentSource($content_source); $editor->setContentSource($content_source);
$editor->setMessage($request->getValue('message')); $editor->setMessage($request->getValue('message'));
$editor->setNoEmail($request->getValue('silent')); $editor->setNoEmail($request->getValue('silent'));

View File

@@ -54,7 +54,7 @@ final class ConduitAPI_differential_createrevision_Method
$revision = DifferentialRevisionEditor::newRevisionFromConduitWithDiff( $revision = DifferentialRevisionEditor::newRevisionFromConduitWithDiff(
$fields, $fields,
$diff, $diff,
$request->getUser()->getPHID()); $request->getUser());
return array( return array(
'revisionid' => $revision->getID(), 'revisionid' => $revision->getID(),

View File

@@ -67,8 +67,8 @@ final class ConduitAPI_differential_markcommitted_Method
$editor = new DifferentialCommentEditor( $editor = new DifferentialCommentEditor(
$revision, $revision,
$request->getUser()->getPHID(),
DifferentialAction::ACTION_CLOSE); DifferentialAction::ACTION_CLOSE);
$editor->setActor($request->getUser());
$editor->save(); $editor->save();
} }

View File

@@ -72,8 +72,8 @@ final class ConduitAPI_differential_updaterevision_Method
array()); array());
$editor = new DifferentialRevisionEditor( $editor = new DifferentialRevisionEditor(
$revision, $revision);
$revision->getAuthorPHID()); $editor->setActor($request->getUser());
$editor->setContentSource($content_source); $editor->setContentSource($content_source);
$fields = $request->getValue('fields'); $fields = $request->getValue('fields');
$editor->copyFieldsFromConduit($fields); $editor->copyFieldsFromConduit($fields);

View File

@@ -196,6 +196,7 @@ abstract class ConduitAPI_maniphest_Method extends ConduitAPIMethod {
$transactions = $event->getValue('transactions'); $transactions = $event->getValue('transactions');
$editor = new ManiphestTransactionEditor(); $editor = new ManiphestTransactionEditor();
$editor->setActor($request->getUser());
$editor->applyTransactions($task, $transactions); $editor->applyTransactions($task, $transactions);
$event = new PhabricatorEvent( $event = new PhabricatorEvent(

View File

@@ -48,7 +48,7 @@ final class ConduitAPI_phriction_edit_Method
$slug = $request->getValue('slug'); $slug = $request->getValue('slug');
$editor = id(PhrictionDocumentEditor::newForSlug($slug)) $editor = id(PhrictionDocumentEditor::newForSlug($slug))
->setUser($request->getUser()) ->setActor($request->getUser())
->setTitle($request->getValue('title')) ->setTitle($request->getValue('title'))
->setContent($request->getValue('content')) ->setContent($request->getValue('content'))
->setDescription($request->getvalue('description')) ->setDescription($request->getvalue('description'))

View File

@@ -138,8 +138,10 @@ class DifferentialReplyHandler extends PhabricatorMailReplyHandler {
try { try {
$editor = new DifferentialCommentEditor( $editor = new DifferentialCommentEditor(
$this->getMailReceiver(), $this->getMailReceiver(),
$actor->getPHID(),
$command); $command);
$editor->setActor($actor);
$editor->setExcludeMailRecipientPHIDs(
$this->getExcludeMailRecipientPHIDs());
// NOTE: We have to be careful about this because Facebook's // NOTE: We have to be careful about this because Facebook's
// implementation jumps straight into handleAction() and will not have // implementation jumps straight into handleAction() and will not have

View File

@@ -37,7 +37,6 @@ final class DifferentialCommentSaveController extends DifferentialController {
$editor = new DifferentialCommentEditor( $editor = new DifferentialCommentEditor(
$revision, $revision,
$request->getUser()->getPHID(),
$action); $action);
$content_source = PhabricatorContentSource::newForSource( $content_source = PhabricatorContentSource::newForSource(
@@ -48,6 +47,7 @@ final class DifferentialCommentSaveController extends DifferentialController {
try { try {
$editor $editor
->setActor($request->getUser())
->setMessage($comment) ->setMessage($comment)
->setContentSource($content_source) ->setContentSource($content_source)
->setAttachInlineComments(true) ->setAttachInlineComments(true)

View File

@@ -62,8 +62,6 @@ final class DifferentialRevisionEditController extends DifferentialController {
if ($request->isFormPost() && !$request->getStr('viaDiffView')) { if ($request->isFormPost() && !$request->getStr('viaDiffView')) {
$user_phid = $request->getUser()->getPHID();
foreach ($aux_fields as $aux_field) { foreach ($aux_fields as $aux_field) {
$aux_field->setValueFromRequest($request); $aux_field->setValueFromRequest($request);
try { try {
@@ -74,7 +72,8 @@ final class DifferentialRevisionEditController extends DifferentialController {
} }
if (!$errors) { if (!$errors) {
$editor = new DifferentialRevisionEditor($revision, $user_phid); $editor = new DifferentialRevisionEditor($revision);
$editor->setActor($request->getUser());
if ($diff) { if ($diff) {
$editor->addDiff($diff, $request->getStr('comments')); $editor->addDiff($diff, $request->getStr('comments'));
} }

View File

@@ -16,10 +16,9 @@
* limitations under the License. * limitations under the License.
*/ */
final class DifferentialCommentEditor { final class DifferentialCommentEditor extends PhabricatorEditor {
protected $revision; protected $revision;
protected $actorPHID;
protected $action; protected $action;
protected $attachInlineComments; protected $attachInlineComments;
@@ -37,11 +36,9 @@ final class DifferentialCommentEditor {
public function __construct( public function __construct(
DifferentialRevision $revision, DifferentialRevision $revision,
$actor_phid,
$action) { $action) {
$this->revision = $revision; $this->revision = $revision;
$this->actorPHID = $actor_phid;
$this->action = $action; $this->action = $action;
} }
@@ -112,16 +109,16 @@ final class DifferentialCommentEditor {
} }
public function save() { public function save() {
$revision = $this->revision; $actor = $this->requireActor();
$action = $this->action; $revision = $this->revision;
$actor_phid = $this->actorPHID; $action = $this->action;
$actor = id(new PhabricatorUser())->loadOneWhere('PHID = %s', $actor_phid); $actor_phid = $actor->getPHID();
$actor_is_author = ($actor_phid == $revision->getAuthorPHID()); $actor_is_author = ($actor_phid == $revision->getAuthorPHID());
$allow_self_accept = PhabricatorEnv::getEnvConfig( $allow_self_accept = PhabricatorEnv::getEnvConfig(
'differential.allow-self-accept', false); 'differential.allow-self-accept', false);
$always_allow_close = PhabricatorEnv::getEnvConfig( $always_allow_close = PhabricatorEnv::getEnvConfig(
'differential.always-allow-close', false); 'differential.always-allow-close', false);
$revision_status = $revision->getStatus(); $revision_status = $revision->getStatus();
$revision->loadRelationships(); $revision->loadRelationships();
$reviewer_phids = $revision->getReviewers(); $reviewer_phids = $revision->getReviewers();
@@ -135,7 +132,7 @@ final class DifferentialCommentEditor {
if ($this->attachInlineComments) { if ($this->attachInlineComments) {
$inline_comments = id(new DifferentialInlineComment())->loadAllWhere( $inline_comments = id(new DifferentialInlineComment())->loadAllWhere(
'authorPHID = %s AND revisionID = %d AND commentID IS NULL', 'authorPHID = %s AND revisionID = %d AND commentID IS NULL',
$this->actorPHID, $actor_phid,
$revision->getID()); $revision->getID());
} }
@@ -414,7 +411,7 @@ final class DifferentialCommentEditor {
DifferentialRevisionEditor::addCC( DifferentialRevisionEditor::addCC(
$revision, $revision,
$cc, $cc,
$this->actorPHID); $actor_phid);
} }
$key = DifferentialComment::METADATA_ADDED_CCS; $key = DifferentialComment::METADATA_ADDED_CCS;
@@ -490,12 +487,12 @@ final class DifferentialCommentEditor {
if ($action != DifferentialAction::ACTION_RESIGN) { if ($action != DifferentialAction::ACTION_RESIGN) {
DifferentialRevisionEditor::addCC( DifferentialRevisionEditor::addCC(
$revision, $revision,
$this->actorPHID, $actor_phid,
$this->actorPHID); $actor_phid);
} }
$comment = id(new DifferentialComment()) $comment = id(new DifferentialComment())
->setAuthorPHID($this->actorPHID) ->setAuthorPHID($actor_phid)
->setRevisionID($revision->getID()) ->setRevisionID($revision->getID())
->setAction($action) ->setAction($action)
->setContent((string)$this->message) ->setContent((string)$this->message)
@@ -541,7 +538,7 @@ final class DifferentialCommentEditor {
DifferentialRevisionEditor::addCC( DifferentialRevisionEditor::addCC(
$revision, $revision,
$cc_phid, $cc_phid,
$this->actorPHID); $actor_phid);
$metacc[] = $cc_phid; $metacc[] = $cc_phid;
} }
$metadata[DifferentialComment::METADATA_ADDED_CCS] = $metacc; $metadata[DifferentialComment::METADATA_ADDED_CCS] = $metacc;
@@ -553,10 +550,10 @@ final class DifferentialCommentEditor {
$revision->saveTransaction(); $revision->saveTransaction();
$phids = array($this->actorPHID); $phids = array($actor_phid);
$handles = id(new PhabricatorObjectHandleData($phids)) $handles = id(new PhabricatorObjectHandleData($phids))
->loadHandles(); ->loadHandles();
$actor_handle = $handles[$this->actorPHID]; $actor_handle = $handles[$actor_phid];
$xherald_header = HeraldTranscript::loadXHeraldRulesHeader( $xherald_header = HeraldTranscript::loadXHeraldRulesHeader(
$revision->getPHID()); $revision->getPHID());
@@ -568,6 +565,7 @@ final class DifferentialCommentEditor {
$comment, $comment,
$changesets, $changesets,
$inline_comments)) $inline_comments))
->setExcludeMailRecipientPHIDs($this->getExcludeMailRecipientPHIDs())
->setToPHIDs( ->setToPHIDs(
array_merge( array_merge(
$revision->getReviewers(), $revision->getReviewers(),
@@ -586,7 +584,7 @@ final class DifferentialCommentEditor {
'revision_author_phid' => $revision->getAuthorPHID(), 'revision_author_phid' => $revision->getAuthorPHID(),
'action' => $comment->getAction(), 'action' => $comment->getAction(),
'feedback_content' => $comment->getContent(), 'feedback_content' => $comment->getContent(),
'actor_phid' => $this->actorPHID, 'actor_phid' => $actor_phid,
); );
id(new PhabricatorTimelineEvent('difx', $event_data)) id(new PhabricatorTimelineEvent('difx', $event_data))
->recordEvent(); ->recordEvent();
@@ -596,11 +594,11 @@ final class DifferentialCommentEditor {
->setStoryType(PhabricatorFeedStoryTypeConstants::STORY_DIFFERENTIAL) ->setStoryType(PhabricatorFeedStoryTypeConstants::STORY_DIFFERENTIAL)
->setStoryData($event_data) ->setStoryData($event_data)
->setStoryTime(time()) ->setStoryTime(time())
->setStoryAuthorPHID($this->actorPHID) ->setStoryAuthorPHID($actor_phid)
->setRelatedPHIDs( ->setRelatedPHIDs(
array( array(
$revision->getPHID(), $revision->getPHID(),
$this->actorPHID, $actor_phid,
$revision->getAuthorPHID(), $revision->getAuthorPHID(),
)) ))
->setPrimaryObjectPHID($revision->getPHID()) ->setPrimaryObjectPHID($revision->getPHID())
@@ -642,10 +640,11 @@ final class DifferentialCommentEditor {
} }
private function alterReviewers() { private function alterReviewers() {
$revision = $this->revision; $actor_phid = $this->getActor()->getPHID();
$added_reviewers = $this->getAddedReviewers(); $revision = $this->revision;
$added_reviewers = $this->getAddedReviewers();
$removed_reviewers = $this->getRemovedReviewers(); $removed_reviewers = $this->getRemovedReviewers();
$reviewer_phids = $revision->getReviewers(); $reviewer_phids = $revision->getReviewers();
$reviewer_phids_map = array_fill_keys($reviewer_phids, true); $reviewer_phids_map = array_fill_keys($reviewer_phids, true);
foreach ($added_reviewers as $k => $user_phid) { foreach ($added_reviewers as $k => $user_phid) {
@@ -672,7 +671,7 @@ final class DifferentialCommentEditor {
$reviewer_phids, $reviewer_phids,
$removed_reviewers, $removed_reviewers,
$added_reviewers, $added_reviewers,
$this->actorPHID); $actor_phid);
} }
return array($added_reviewers, $removed_reviewers); return array($added_reviewers, $removed_reviewers);

View File

@@ -21,10 +21,9 @@
* reviewers, diffs, and CCs. Unlike simple edits, these changes trigger * reviewers, diffs, and CCs. Unlike simple edits, these changes trigger
* complicated email workflows. * complicated email workflows.
*/ */
final class DifferentialRevisionEditor { final class DifferentialRevisionEditor extends PhabricatorEditor {
protected $revision; protected $revision;
protected $actorPHID;
protected $cc = null; protected $cc = null;
protected $reviewers = null; protected $reviewers = null;
@@ -35,24 +34,22 @@ final class DifferentialRevisionEditor {
private $auxiliaryFields = array(); private $auxiliaryFields = array();
private $contentSource; private $contentSource;
public function __construct(DifferentialRevision $revision, $actor_phid) { public function __construct(DifferentialRevision $revision) {
$this->revision = $revision; $this->revision = $revision;
$this->actorPHID = $actor_phid;
} }
public static function newRevisionFromConduitWithDiff( public static function newRevisionFromConduitWithDiff(
array $fields, array $fields,
DifferentialDiff $diff, DifferentialDiff $diff,
$user_phid) { PhabricatorUser $actor) {
$revision = new DifferentialRevision(); $revision = new DifferentialRevision();
$revision->setPHID($revision->generatePHID()); $revision->setPHID($revision->generatePHID());
$revision->setAuthorPHID($actor->getPHID());
$revision->setAuthorPHID($user_phid);
$revision->setStatus(ArcanistDifferentialRevisionStatus::NEEDS_REVIEW); $revision->setStatus(ArcanistDifferentialRevisionStatus::NEEDS_REVIEW);
$editor = new DifferentialRevisionEditor($revision, $user_phid); $editor = new DifferentialRevisionEditor($revision);
$editor->setActor($actor);
$editor->copyFieldsFromConduit($fields); $editor->copyFieldsFromConduit($fields);
$editor->addDiff($diff, null); $editor->addDiff($diff, null);
@@ -63,19 +60,16 @@ final class DifferentialRevisionEditor {
public function copyFieldsFromConduit(array $fields) { public function copyFieldsFromConduit(array $fields) {
$actor = $this->getActor();
$revision = $this->revision; $revision = $this->revision;
$revision->loadRelationships(); $revision->loadRelationships();
$aux_fields = DifferentialFieldSelector::newSelector() $aux_fields = DifferentialFieldSelector::newSelector()
->getFieldSpecifications(); ->getFieldSpecifications();
$user = id(new PhabricatorUser())->loadOneWhere(
'phid = %s',
$this->actorPHID);
foreach ($aux_fields as $key => $aux_field) { foreach ($aux_fields as $key => $aux_field) {
$aux_field->setRevision($revision); $aux_field->setRevision($revision);
$aux_field->setUser($user); $aux_field->setUser($actor);
if (!$aux_field->shouldAppearOnCommitMessage()) { if (!$aux_field->shouldAppearOnCommitMessage()) {
unset($aux_fields[$key]); unset($aux_fields[$key]);
} }

View File

@@ -102,7 +102,7 @@ abstract class DifferentialFreeformFieldSpecification
} }
id(new PhabricatorEdgeEditor()) id(new PhabricatorEdgeEditor())
->setUser($user) ->setActor($user)
->addEdge( ->addEdge(
$task->getPHID(), $task->getPHID(),
PhabricatorEdgeConfig::TYPE_TASK_HAS_COMMIT, PhabricatorEdgeConfig::TYPE_TASK_HAS_COMMIT,

View File

@@ -74,7 +74,7 @@ final class DifferentialManiphestTasksFieldSpecification
$rem_phids = array_diff($old_phids, $add_phids); $rem_phids = array_diff($old_phids, $add_phids);
$edge_editor = id(new PhabricatorEdgeEditor()) $edge_editor = id(new PhabricatorEdgeEditor())
->setUser($this->getUser()); ->setActor($this->getUser());
foreach ($add_phids as $phid) { foreach ($add_phids as $phid) {
$edge_editor->addEdge($revision_phid, $edge_type, $phid); $edge_editor->addEdge($revision_phid, $edge_type, $phid);

View File

@@ -20,6 +20,7 @@ abstract class DifferentialMail {
protected $to = array(); protected $to = array();
protected $cc = array(); protected $cc = array();
protected $excludePHIDs = array();
protected $actorHandle; protected $actorHandle;
@@ -91,6 +92,7 @@ abstract class DifferentialMail {
$template $template
->setIsHTML($this->shouldMarkMailAsHTML()) ->setIsHTML($this->shouldMarkMailAsHTML())
->setParentMessageID($this->parentMessageID) ->setParentMessageID($this->parentMessageID)
->setExcludeMailRecipientPHIDs($this->getExcludeMailRecipientPHIDs())
->addHeader('Thread-Topic', $this->getThreadTopic()); ->addHeader('Thread-Topic', $this->getThreadTopic());
$template->setAttachments($attachments); $template->setAttachments($attachments);
@@ -315,37 +317,25 @@ abstract class DifferentialMail {
return implode("\n", $text); return implode("\n", $text);
} }
public function setExcludeMailRecipientPHIDs(array $exclude) {
$this->excludePHIDs = $exclude;
return $this;
}
public function getExcludeMailRecipientPHIDs() {
return $this->excludePHIDs;
}
public function setToPHIDs(array $to) { public function setToPHIDs(array $to) {
$this->to = $this->filterContactPHIDs($to); $this->to = $to;
return $this; return $this;
} }
public function setCCPHIDs(array $cc) { public function setCCPHIDs(array $cc) {
$this->cc = $this->filterContactPHIDs($cc); $this->cc = $cc;
return $this; return $this;
} }
protected function filterContactPHIDs(array $phids) {
return $phids;
// TODO: actually do this?
// Differential revisions use Subscriptions for CCs, so any arbitrary
// PHID can end up CC'd to them. Only try to actually send email PHIDs
// which have ToolsHandle types that are marked emailable. If we don't
// filter here, sending the email will fail.
/*
$handles = array();
prep(new ToolsHandleData($phids, $handles));
foreach ($handles as $phid => $handle) {
if (!$handle->isEmailable()) {
unset($handles[$phid]);
}
}
return array_keys($handles);
*/
}
protected function getToPHIDs() { protected function getToPHIDs() {
return $this->to; return $this->to;
} }

View File

@@ -51,7 +51,7 @@ final class DiffusionCommitEditController extends DiffusionController {
$rem_proj_phids = array_diff($current_proj_phids, $rem_proj_phids = array_diff($current_proj_phids,
$new_proj_phids); $new_proj_phids);
$editor = id(new PhabricatorEdgeEditor()); $editor = id(new PhabricatorEdgeEditor());
$editor->setUser($user); $editor->setActor($user);
foreach ($rem_proj_phids as $phid) { foreach ($rem_proj_phids as $phid) {
$editor->removeEdge($commit_phid, $edge_type, $phid); $editor->removeEdge($commit_phid, $edge_type, $phid);
} }

View File

@@ -167,7 +167,10 @@ final class ManiphestReplyHandler extends PhabricatorMailReplyHandler {
$editor = new ManiphestTransactionEditor(); $editor = new ManiphestTransactionEditor();
$editor->setActor($user);
$editor->setParentMessageID($mail->getMessageID()); $editor->setParentMessageID($mail->getMessageID());
$editor->setExcludeMailRecipientPHIDs(
$this->getExcludeMailRecipientPHIDs());
$editor->applyTransactions($task, $xactions); $editor->applyTransactions($task, $xactions);
$event = new PhabricatorEvent( $event = new PhabricatorEvent(

View File

@@ -41,6 +41,7 @@ final class ManiphestBatchEditController extends ManiphestController {
$xactions = $this->buildTransactions($actions, $task); $xactions = $this->buildTransactions($actions, $task);
if ($xactions) { if ($xactions) {
$editor = new ManiphestTransactionEditor(); $editor = new ManiphestTransactionEditor();
$editor->setActor($user);
$editor->applyTransactions($task, $xactions); $editor->applyTransactions($task, $xactions);
} }
} }

View File

@@ -59,6 +59,7 @@ final class ManiphestSubpriorityController extends ManiphestController {
$xaction->setNewValue($after_pri); $xaction->setNewValue($after_pri);
$editor = new ManiphestTransactionEditor(); $editor = new ManiphestTransactionEditor();
$editor->setActor($request->getUser());
$editor->applyTransactions($task, array($xaction)); $editor->applyTransactions($task, array($xaction));
} }

View File

@@ -231,6 +231,7 @@ final class ManiphestTaskEditController extends ManiphestController {
$transactions = $event->getValue('transactions'); $transactions = $event->getValue('transactions');
$editor = new ManiphestTransactionEditor(); $editor = new ManiphestTransactionEditor();
$editor->setActor($user);
$editor->setAuxiliaryFields($aux_fields); $editor->setAuxiliaryFields($aux_fields);
$editor->applyTransactions($task, $transactions); $editor->applyTransactions($task, $transactions);

View File

@@ -244,6 +244,7 @@ final class ManiphestTransactionSaveController extends ManiphestController {
$transactions = $event->getValue('transactions'); $transactions = $event->getValue('transactions');
$editor = new ManiphestTransactionEditor(); $editor = new ManiphestTransactionEditor();
$editor->setActor($user);
$editor->applyTransactions($task, $transactions); $editor->applyTransactions($task, $transactions);
$draft = id(new PhabricatorDraft())->loadOneWhere( $draft = id(new PhabricatorDraft())->loadOneWhere(

View File

@@ -19,9 +19,10 @@
/** /**
* @group maniphest * @group maniphest
*/ */
final class ManiphestTransactionEditor { final class ManiphestTransactionEditor extends PhabricatorEditor {
private $parentMessageID; private $parentMessageID;
private $excludePHIDs = array();
private $auxiliaryFields = array(); private $auxiliaryFields = array();
public function setAuxiliaryFields(array $fields) { public function setAuxiliaryFields(array $fields) {
@@ -35,6 +36,15 @@ final class ManiphestTransactionEditor {
return $this; return $this;
} }
public function setExcludePHIDs(array $exclude) {
$this->excludePHIDs = $exclude;
return $this;
}
public function getExcludePHIDs() {
return $this->excludePHIDs;
}
public function applyTransactions(ManiphestTask $task, array $transactions) { public function applyTransactions(ManiphestTask $task, array $transactions) {
assert_instances_of($transactions, 'ManiphestTransaction'); assert_instances_of($transactions, 'ManiphestTransaction');
@@ -221,6 +231,7 @@ final class ManiphestTransactionEditor {
} }
private function sendEmail($task, $transactions, $email_to, $email_cc) { private function sendEmail($task, $transactions, $email_to, $email_cc) {
$exclude = $this->getExcludePHIDs();
$email_to = array_filter(array_unique($email_to)); $email_to = array_filter(array_unique($email_to));
$email_cc = array_filter(array_unique($email_cc)); $email_cc = array_filter(array_unique($email_cc));
@@ -276,6 +287,7 @@ final class ManiphestTransactionEditor {
->addHeader('Thread-Topic', "T{$task_id}: ".$task->getOriginalTitle()) ->addHeader('Thread-Topic', "T{$task_id}: ".$task->getOriginalTitle())
->setThreadID($thread_id, $is_create) ->setThreadID($thread_id, $is_create)
->setRelatedPHID($task->getPHID()) ->setRelatedPHID($task->getPHID())
->setExcludeMailRecipientPHIDs($this->getExcludeMailRecipientPHIDs())
->setIsBulk(true) ->setIsBulk(true)
->setMailTags($mailtags) ->setMailTags($mailtags)
->setBody($body->render()); ->setBody($body->render());

View File

@@ -73,6 +73,7 @@ final class ManiphestEdgeEventListener extends PhutilEventListener {
$new_edges = $this->loadAllEdges($event); $new_edges = $this->loadAllEdges($event);
$editor = new ManiphestTransactionEditor(); $editor = new ManiphestTransactionEditor();
$editor->setActor($event->getUser());
foreach ($tasks as $phid => $task) { foreach ($tasks as $phid => $task) {
$xactions = array(); $xactions = array();

View File

@@ -20,6 +20,7 @@ abstract class PhabricatorMailReplyHandler {
private $mailReceiver; private $mailReceiver;
private $actor; private $actor;
private $excludePHIDs = array();
final public function setMailReceiver($mail_receiver) { final public function setMailReceiver($mail_receiver) {
$this->validateMailReceiver($mail_receiver); $this->validateMailReceiver($mail_receiver);
@@ -40,6 +41,15 @@ abstract class PhabricatorMailReplyHandler {
return $this->actor; return $this->actor;
} }
final public function setExcludeMailRecipientPHIDs(array $exclude) {
$this->excludePHIDs = $exclude;
return $this;
}
final public function getExcludeMailRecipientPHIDs() {
return $this->excludePHIDs;
}
abstract public function validateMailReceiver($mail_receiver); abstract public function validateMailReceiver($mail_receiver);
abstract public function getPrivateReplyHandlerEmailAddress( abstract public function getPrivateReplyHandlerEmailAddress(
PhabricatorObjectHandle $handle); PhabricatorObjectHandle $handle);

View File

@@ -36,6 +36,8 @@ final class PhabricatorMetaMTAMail extends PhabricatorMetaMTADAO {
protected $nextRetry; protected $nextRetry;
protected $relatedPHID; protected $relatedPHID;
private $excludePHIDs = array();
public function __construct() { public function __construct() {
$this->status = self::STATUS_QUEUE; $this->status = self::STATUS_QUEUE;
@@ -119,6 +121,14 @@ final class PhabricatorMetaMTAMail extends PhabricatorMetaMTADAO {
return $this; return $this;
} }
public function setExcludeMailRecipientPHIDs($exclude) {
$this->excludePHIDs = $exclude;
return $this;
}
private function getExcludeMailRecipientPHIDs() {
return $this->excludePHIDs;
}
public function getTranslation(array $objects) { public function getTranslation(array $objects) {
$default_translation = PhabricatorEnv::getEnvConfig('translation.provider'); $default_translation = PhabricatorEnv::getEnvConfig('translation.provider');
$return = null; $return = null;
@@ -349,7 +359,7 @@ final class PhabricatorMetaMTAMail extends PhabricatorMetaMTADAO {
$this->loadEmailAndNameDataFromPHIDs($phids); $this->loadEmailAndNameDataFromPHIDs($phids);
$exclude = array(); $exclude = array_fill_keys($this->getExcludeMailRecipientPHIDs(), true);
$params = $this->parameters; $params = $this->parameters;
$default = PhabricatorEnv::getEnvConfig('metamta.default-address'); $default = PhabricatorEnv::getEnvConfig('metamta.default-address');

View File

@@ -62,6 +62,23 @@ final class PhabricatorMetaMTAReceivedMail extends PhabricatorMetaMTADAO {
return $this->getRawEmailAddresses(idx($this->headers, 'to')); return $this->getRawEmailAddresses(idx($this->headers, 'to'));
} }
private function loadExcludeMailRecipientPHIDs() {
$addresses = array_merge(
$this->getToAddresses(),
$this->getCCAddresses()
);
$users = id(new PhabricatorUserEmail())
->loadAllWhere('address IN (%Ls)', $addresses);
$user_phids = mpull($users, 'getUserPHID');
$mailing_lists = id(new PhabricatorMetaMTAMailingList())
->loadAllWhere('email in (%Ls)', $addresses);
$mailing_list_phids = mpull($mailing_lists, 'getPHID');
return array_merge($user_phids, $mailing_list_phids);
}
/** /**
* Parses "to" addresses, looking for a public create email address * Parses "to" addresses, looking for a public create email address
* first and if not found parsing the "to" address for reply handler * first and if not found parsing the "to" address for reply handler
@@ -182,9 +199,12 @@ final class PhabricatorMetaMTAReceivedMail extends PhabricatorMetaMTADAO {
$receiver->setPriority(ManiphestTaskPriority::PRIORITY_TRIAGE); $receiver->setPriority(ManiphestTaskPriority::PRIORITY_TRIAGE);
$editor = new ManiphestTransactionEditor(); $editor = new ManiphestTransactionEditor();
$editor->setActor($user);
$handler = $editor->buildReplyHandler($receiver); $handler = $editor->buildReplyHandler($receiver);
$handler->setActor($user); $handler->setActor($user);
$handler->setExcludeMailRecipientPHIDs(
$this->loadExcludeMailRecipientPHIDs());
$handler->processEmail($this); $handler->processEmail($this);
$this->setRelatedPHID($receiver->getPHID()); $this->setRelatedPHID($receiver->getPHID());
@@ -248,6 +268,7 @@ final class PhabricatorMetaMTAReceivedMail extends PhabricatorMetaMTADAO {
if ($receiver instanceof ManiphestTask) { if ($receiver instanceof ManiphestTask) {
$editor = new ManiphestTransactionEditor(); $editor = new ManiphestTransactionEditor();
$editor->setActor($user);
$handler = $editor->buildReplyHandler($receiver); $handler = $editor->buildReplyHandler($receiver);
} else if ($receiver instanceof DifferentialRevision) { } else if ($receiver instanceof DifferentialRevision) {
$handler = DifferentialMail::newReplyHandlerForRevision($receiver); $handler = DifferentialMail::newReplyHandlerForRevision($receiver);
@@ -257,6 +278,8 @@ final class PhabricatorMetaMTAReceivedMail extends PhabricatorMetaMTADAO {
} }
$handler->setActor($user); $handler->setActor($user);
$handler->setExcludeMailRecipientPHIDs(
$this->loadExcludeMailRecipientPHIDs());
$handler->processEmail($this); $handler->processEmail($this);
$this->setMessage('OK'); $this->setMessage('OK');

View File

@@ -26,24 +26,11 @@
* @task email Adding, Removing and Changing Email * @task email Adding, Removing and Changing Email
* @task internal Internals * @task internal Internals
*/ */
final class PhabricatorUserEditor { final class PhabricatorUserEditor extends PhabricatorEditor {
private $actor;
private $logs = array(); private $logs = array();
/* -( Configuration )------------------------------------------------------ */
/**
* @task config
*/
public function setActor(PhabricatorUser $actor) {
$this->actor = $actor;
return $this;
}
/* -( Creating and Editing Users )----------------------------------------- */ /* -( Creating and Editing Users )----------------------------------------- */
@@ -88,7 +75,7 @@ final class PhabricatorUserEditor {
} }
$log = PhabricatorUserLog::newLog( $log = PhabricatorUserLog::newLog(
$this->actor, $this->getActor(),
$user, $user,
PhabricatorUserLog::ACTION_CREATE); PhabricatorUserLog::ACTION_CREATE);
$log->setNewValue($email->getAddress()); $log->setNewValue($email->getAddress());
@@ -147,7 +134,7 @@ final class PhabricatorUserEditor {
$user->save(); $user->save();
$log = PhabricatorUserLog::newLog( $log = PhabricatorUserLog::newLog(
$this->actor, $this->getActor(),
$user, $user,
PhabricatorUserLog::ACTION_CHANGE_PASSWORD); PhabricatorUserLog::ACTION_CHANGE_PASSWORD);
$log->save(); $log->save();
@@ -186,7 +173,7 @@ final class PhabricatorUserEditor {
} }
$log = PhabricatorUserLog::newLog( $log = PhabricatorUserLog::newLog(
$this->actor, $actor,
$user, $user,
PhabricatorUserLog::ACTION_CHANGE_USERNAME); PhabricatorUserLog::ACTION_CHANGE_USERNAME);
$log->setOldValue($old_username); $log->setOldValue($old_username);
@@ -429,7 +416,7 @@ final class PhabricatorUserEditor {
} }
$log = PhabricatorUserLog::newLog( $log = PhabricatorUserLog::newLog(
$this->actor, $actor,
$user, $user,
PhabricatorUserLog::ACTION_EMAIL_ADD); PhabricatorUserLog::ACTION_EMAIL_ADD);
$log->setNewValue($email->getAddress()); $log->setNewValue($email->getAddress());
@@ -474,7 +461,7 @@ final class PhabricatorUserEditor {
$email->delete(); $email->delete();
$log = PhabricatorUserLog::newLog( $log = PhabricatorUserLog::newLog(
$this->actor, $actor,
$user, $user,
PhabricatorUserLog::ACTION_EMAIL_REMOVE); PhabricatorUserLog::ACTION_EMAIL_REMOVE);
$log->setOldValue($email->getAddress()); $log->setOldValue($email->getAddress());
@@ -553,17 +540,6 @@ final class PhabricatorUserEditor {
/* -( Internals )---------------------------------------------------------- */ /* -( Internals )---------------------------------------------------------- */
/**
* @task internal
*/
private function requireActor() {
if (!$this->actor) {
throw new Exception("User edit requires actor!");
}
return $this->actor;
}
/** /**
* @task internal * @task internal
*/ */

View File

@@ -88,8 +88,8 @@ extends PhameController {
$blogger_phids = array_keys($blogger_edges); $blogger_phids = array_keys($blogger_edges);
$post_edges = $edges[$blog_phid][$post_edge_type]; $post_edges = $edges[$blog_phid][$post_edge_type];
$post_phids = array_keys($post_edges); $post_phids = array_keys($post_edges);
$editor = id(new PhabricatorEdgeEditor()); $editor = id(new PhabricatorEdgeEditor())
$editor->setUser($user); ->setActor($user);
foreach ($blogger_phids as $phid) { foreach ($blogger_phids as $phid) {
$editor->removeEdge($blog_phid, $blogger_edge_type, $phid); $editor->removeEdge($blog_phid, $blogger_edge_type, $phid);
} }

View File

@@ -163,7 +163,7 @@ final class PhameBlogEditController
$rem_phids = array_diff($old_bloggers, $new_bloggers); $rem_phids = array_diff($old_bloggers, $new_bloggers);
$editor = new PhabricatorEdgeEditor(); $editor = new PhabricatorEdgeEditor();
$edge_type = PhabricatorEdgeConfig::TYPE_BLOG_HAS_BLOGGER; $edge_type = PhabricatorEdgeConfig::TYPE_BLOG_HAS_BLOGGER;
$editor->setUser($user); $editor->setActor($user);
foreach ($add_phids as $phid) { foreach ($add_phids as $phid) {
$editor->addEdge($blog->getPHID(), $edge_type, $phid); $editor->addEdge($blog->getPHID(), $edge_type, $phid);
} }

View File

@@ -62,8 +62,8 @@ extends PhameController {
$blog_edges = $edges[$post_phid][$edge_type]; $blog_edges = $edges[$post_phid][$edge_type];
$blog_phids = array_keys($blog_edges); $blog_phids = array_keys($blog_edges);
$editor = id(new PhabricatorEdgeEditor()); $editor = id(new PhabricatorEdgeEditor())
$editor->setUser($user); ->setActor($user);
foreach ($blog_phids as $phid) { foreach ($blog_phids as $phid) {
$editor->removeEdge($post_phid, $edge_type, $phid); $editor->removeEdge($post_phid, $edge_type, $phid);
} }

View File

@@ -198,7 +198,7 @@ final class PhamePostEditController
$editor = new PhabricatorEdgeEditor(); $editor = new PhabricatorEdgeEditor();
$edge_type = PhabricatorEdgeConfig::TYPE_POST_HAS_BLOG; $edge_type = PhabricatorEdgeConfig::TYPE_POST_HAS_BLOG;
$editor->setUser($user); $editor->setActor($user);
foreach ($blogs_to_publish as $phid) { foreach ($blogs_to_publish as $phid) {
$editor->addEdge($post->getPHID(), $edge_type, $phid); $editor->addEdge($post->getPHID(), $edge_type, $phid);
} }

View File

@@ -41,7 +41,7 @@ final class PhrictionDeleteController extends PhrictionController {
if ($request->isFormPost()) { if ($request->isFormPost()) {
$editor = id(PhrictionDocumentEditor::newForSlug($document->getSlug())) $editor = id(PhrictionDocumentEditor::newForSlug($document->getSlug()))
->setUser($user) ->setActor($user)
->delete(); ->delete();
return id(new AphrontRedirectResponse())->setURI($document_uri); return id(new AphrontRedirectResponse())->setURI($document_uri);
} }

View File

@@ -134,7 +134,7 @@ final class PhrictionEditController
if (!count($errors)) { if (!count($errors)) {
$editor = id(PhrictionDocumentEditor::newForSlug($document->getSlug())) $editor = id(PhrictionDocumentEditor::newForSlug($document->getSlug()))
->setUser($user) ->setActor($user)
->setTitle($title) ->setTitle($title)
->setContent($request->getStr('content')) ->setContent($request->getStr('content'))
->setDescription($notes); ->setDescription($notes);

View File

@@ -21,13 +21,11 @@
* *
* @group phriction * @group phriction
*/ */
final class PhrictionDocumentEditor { final class PhrictionDocumentEditor extends PhabricatorEditor {
private $document; private $document;
private $content; private $content;
private $user;
private $newTitle; private $newTitle;
private $newContent; private $newContent;
private $description; private $description;
@@ -65,11 +63,6 @@ final class PhrictionDocumentEditor {
return $obj; return $obj;
} }
public function setUser(PhabricatorUser $user) {
$this->user = $user;
return $this;
}
public function setTitle($title) { public function setTitle($title) {
$this->newTitle = $title; $this->newTitle = $title;
return $this; return $this;
@@ -90,9 +83,7 @@ final class PhrictionDocumentEditor {
} }
public function delete() { public function delete() {
if (!$this->user) { $actor = $this->requireActor();
throw new Exception("Call setUser() before deleting a document!");
}
// TODO: Should we do anything about deleting an already-deleted document? // TODO: Should we do anything about deleting an already-deleted document?
// We currently allow it. // We currently allow it.
@@ -109,9 +100,7 @@ final class PhrictionDocumentEditor {
} }
public function save() { public function save() {
if (!$this->user) { $actor = $this->requireActor();
throw new Exception("Call setUser() before updating a document!");
}
if ($this->newContent === '') { if ($this->newContent === '') {
// If this is an edit which deletes all the content, just treat it as // If this is an edit which deletes all the content, just treat it as
@@ -134,7 +123,7 @@ final class PhrictionDocumentEditor {
$new_content = new PhrictionContent(); $new_content = new PhrictionContent();
$new_content->setSlug($document->getSlug()); $new_content->setSlug($document->getSlug());
$new_content->setAuthorPHID($this->user->getPHID()); $new_content->setAuthorPHID($this->getActor()->getPHID());
$new_content->setChangeType(PhrictionChangeType::CHANGE_EDIT); $new_content->setChangeType(PhrictionChangeType::CHANGE_EDIT);
$new_content->setTitle( $new_content->setTitle(
@@ -214,7 +203,7 @@ final class PhrictionDocumentEditor {
$related_phids = array( $related_phids = array(
$document->getPHID(), $document->getPHID(),
$this->user->getPHID(), $this->getActor()->getPHID(),
); );
if ($project_phid) { if ($project_phid) {
@@ -223,7 +212,7 @@ final class PhrictionDocumentEditor {
id(new PhabricatorFeedStoryPublisher()) id(new PhabricatorFeedStoryPublisher())
->setRelatedPHIDs($related_phids) ->setRelatedPHIDs($related_phids)
->setStoryAuthorPHID($this->user->getPHID()) ->setStoryAuthorPHID($this->getActor()->getPHID())
->setStoryTime(time()) ->setStoryTime(time())
->setStoryType(PhabricatorFeedStoryTypeConstants::STORY_PHRICTION) ->setStoryType(PhabricatorFeedStoryTypeConstants::STORY_PHRICTION)
->setStoryData( ->setStoryData(

View File

@@ -60,7 +60,7 @@ final class PonderAnswerSaveController extends PonderController {
->setContentSource($content_source); ->setContentSource($content_source);
id(new PonderAnswerEditor()) id(new PonderAnswerEditor())
->setUser($user) ->setActor($user)
->setQuestion($question) ->setQuestion($question)
->setAnswer($res) ->setAnswer($res)
->saveAnswer(); ->saveAnswer();

View File

@@ -61,7 +61,7 @@ final class PonderCommentSaveController extends PonderController {
->setQuestion($question) ->setQuestion($question)
->setComment($res) ->setComment($res)
->setTargetPHID($target) ->setTargetPHID($target)
->setUser($user) ->setActor($user)
->save(); ->save();
return id(new AphrontRedirectResponse()) return id(new AphrontRedirectResponse())

View File

@@ -53,7 +53,7 @@ final class PonderQuestionAskController extends PonderController {
id(new PonderQuestionEditor()) id(new PonderQuestionEditor())
->setQuestion($question) ->setQuestion($question)
->setUser($user) ->setActor($user)
->save(); ->save();
return id(new AphrontRedirectResponse()) return id(new AphrontRedirectResponse())

View File

@@ -49,7 +49,7 @@ final class PonderVoteSaveController extends PonderController {
$editor = id(new PonderVoteEditor()) $editor = id(new PonderVoteEditor())
->setVotable($target) ->setVotable($target)
->setUser($user) ->setActor($user)
->setVote($newvote) ->setVote($newvote)
->saveVote(); ->saveVote();

View File

@@ -16,10 +16,10 @@
* limitations under the License. * limitations under the License.
*/ */
final class PonderAnswerEditor { final class PonderAnswerEditor extends PhabricatorEditor {
private $question; private $question;
private $answer; private $answer;
private $viewer;
private $shouldEmail = true; private $shouldEmail = true;
public function setQuestion($question) { public function setQuestion($question) {
@@ -32,15 +32,8 @@ final class PonderAnswerEditor {
return $this; return $this;
} }
public function setUser(PhabricatorUser $user) {
$this->viewer = $user;
return $this;
}
public function saveAnswer() { public function saveAnswer() {
if (!$this->viewer) { $actor = $this->requireActor();
throw new Exception("Must set user before saving question");
}
if (!$this->question) { if (!$this->question) {
throw new Exception("Must set question before saving answer"); throw new Exception("Must set question before saving answer");
} }
@@ -50,7 +43,6 @@ final class PonderAnswerEditor {
$question = $this->question; $question = $this->question;
$answer = $this->answer; $answer = $this->answer;
$viewer = $this->viewer;
$conn = $answer->establishConnection('w'); $conn = $answer->establishConnection('w');
$trans = $conn->openTransaction(); $trans = $conn->openTransaction();
$trans->beginReadLocking(); $trans->beginReadLocking();
@@ -76,7 +68,7 @@ final class PonderAnswerEditor {
// subscribe author and @mentions // subscribe author and @mentions
$subeditor = id(new PhabricatorSubscriptionsEditor()) $subeditor = id(new PhabricatorSubscriptionsEditor())
->setObject($question) ->setObject($question)
->setUser($viewer); ->setActor($actor);
$subeditor->subscribeExplicit(array($answer->getAuthorPHID())); $subeditor->subscribeExplicit(array($answer->getAuthorPHID()));
@@ -98,7 +90,7 @@ final class PonderAnswerEditor {
id(new PonderMentionMail( id(new PonderMentionMail(
$question, $question,
$answer, $answer,
$viewer)) $actor))
->setToPHIDs($at_mention_phids) ->setToPHIDs($at_mention_phids)
->send(); ->send();
} }
@@ -115,7 +107,7 @@ final class PonderAnswerEditor {
id(new PonderAnsweredMail( id(new PonderAnsweredMail(
$question, $question,
$answer, $answer,
$viewer)) $actor))
->setToPHIDs($other_subs) ->setToPHIDs($other_subs)
->send(); ->send();
} }

View File

@@ -16,13 +16,11 @@
* limitations under the License. * limitations under the License.
*/ */
final class PonderCommentEditor extends PhabricatorEditor {
final class PonderCommentEditor {
private $question; private $question;
private $comment; private $comment;
private $targetPHID; private $targetPHID;
private $viewer;
private $shouldEmail = true; private $shouldEmail = true;
public function setComment(PonderComment $comment) { public function setComment(PonderComment $comment) {
@@ -40,12 +38,8 @@ final class PonderCommentEditor {
return $this; return $this;
} }
public function setUser(PhabricatorUser $user) {
$this->viewer = $user;
return $this;
}
public function save() { public function save() {
$actor = $this->requireActor();
if (!$this->comment) { if (!$this->comment) {
throw new Exception("Must set comment before saving it"); throw new Exception("Must set comment before saving it");
} }
@@ -55,14 +49,10 @@ final class PonderCommentEditor {
if (!$this->targetPHID) { if (!$this->targetPHID) {
throw new Exception("Must set target before saving comment"); throw new Exception("Must set target before saving comment");
} }
if (!$this->viewer) {
throw new Exception("Must set viewer before saving comment");
}
$comment = $this->comment; $comment = $this->comment;
$question = $this->question; $question = $this->question;
$target = $this->targetPHID; $target = $this->targetPHID;
$viewer = $this->viewer;
$comment->save(); $comment->save();
$question->attachRelated(); $question->attachRelated();
@@ -71,7 +61,7 @@ final class PonderCommentEditor {
// subscribe author and @mentions // subscribe author and @mentions
$subeditor = id(new PhabricatorSubscriptionsEditor()) $subeditor = id(new PhabricatorSubscriptionsEditor())
->setObject($question) ->setObject($question)
->setUser($viewer); ->setActor($actor);
$subeditor->subscribeExplicit(array($comment->getAuthorPHID())); $subeditor->subscribeExplicit(array($comment->getAuthorPHID()));
@@ -92,7 +82,7 @@ final class PonderCommentEditor {
id(new PonderMentionMail( id(new PonderMentionMail(
$question, $question,
$comment, $comment,
$viewer)) $actor))
->setToPHIDs($at_mention_phids) ->setToPHIDs($at_mention_phids)
->send(); ->send();
} }
@@ -124,7 +114,7 @@ final class PonderCommentEditor {
id(new PonderCommentMail( id(new PonderCommentMail(
$question, $question,
$comment, $comment,
$viewer)) $actor))
->setToPHIDs($other_subs) ->setToPHIDs($other_subs)
->send(); ->send();
} }

View File

@@ -16,11 +16,9 @@
* limitations under the License. * limitations under the License.
*/ */
final class PonderQuestionEditor extends PhabricatorEditor {
final class PonderQuestionEditor {
private $question; private $question;
private $viewer;
private $shouldEmail = true; private $shouldEmail = true;
public function setQuestion(PonderQuestion $question) { public function setQuestion(PonderQuestion $question) {
@@ -28,25 +26,17 @@ final class PonderQuestionEditor {
return $this; return $this;
} }
public function setUser(PhabricatorUser $user) {
$this->viewer = $user;
return $this;
}
public function setShouldEmail($se) { public function setShouldEmail($se) {
$this->shouldEmail = $se; $this->shouldEmail = $se;
return $this; return $this;
} }
public function save() { public function save() {
if (!$this->viewer) { $actor = $this->requireActor();
throw new Exception("Must set user before saving question");
}
if (!$this->question) { if (!$this->question) {
throw new Exception("Must set question before saving it"); throw new Exception("Must set question before saving it");
} }
$viewer = $this->viewer;
$question = $this->question; $question = $this->question;
$question->save(); $question->save();
@@ -57,7 +47,7 @@ final class PonderQuestionEditor {
// subscribe author and @mentions // subscribe author and @mentions
$subeditor = id(new PhabricatorSubscriptionsEditor()) $subeditor = id(new PhabricatorSubscriptionsEditor())
->setObject($question) ->setObject($question)
->setUser($viewer); ->setActor($actor);
$subeditor->subscribeExplicit(array($question->getAuthorPHID())); $subeditor->subscribeExplicit(array($question->getAuthorPHID()));
@@ -72,7 +62,7 @@ final class PonderQuestionEditor {
id(new PonderMentionMail( id(new PonderMentionMail(
$question, $question,
$question, $question,
$viewer)) $actor))
->setToPHIDs($at_mention_phids) ->setToPHIDs($at_mention_phids)
->send(); ->send();
} }

View File

@@ -16,13 +16,11 @@
* limitations under the License. * limitations under the License.
*/ */
final class PonderVoteEditor extends PhabricatorEditor {
final class PonderVoteEditor {
private $answer; private $answer;
private $votable; private $votable;
private $anwer; private $anwer;
private $user;
private $vote; private $vote;
public function setAnswer($answer) { public function setAnswer($answer) {
@@ -35,39 +33,31 @@ final class PonderVoteEditor {
return $this; return $this;
} }
public function setUser($user) {
$this->user = $user;
return $this;
}
public function setVote($vote) { public function setVote($vote) {
$this->vote = $vote; $this->vote = $vote;
return $this; return $this;
} }
public function saveVote() { public function saveVote() {
$actor = $this->requireActor();
if (!$this->votable) { if (!$this->votable) {
throw new Exception("Must set votable before saving vote"); throw new Exception("Must set votable before saving vote");
} }
if (!$this->user) {
throw new Exception("Must set user before saving vote");
}
$user = $this->user;
$votable = $this->votable; $votable = $this->votable;
$newvote = $this->vote; $newvote = $this->vote;
// prepare vote add, or update if this user is amending an // prepare vote add, or update if this user is amending an
// earlier vote // earlier vote
$editor = id(new PhabricatorEdgeEditor()) $editor = id(new PhabricatorEdgeEditor())
->setUser($user) ->setActor($actor)
->addEdge( ->addEdge(
$user->getPHID(), $actor->getPHID(),
$votable->getUserVoteEdgeType(), $votable->getUserVoteEdgeType(),
$votable->getVotablePHID(), $votable->getVotablePHID(),
array('data' => $newvote)) array('data' => $newvote))
->removeEdge( ->removeEdge(
$user->getPHID(), $actor->getPHID(),
$votable->getUserVoteEdgeType(), $votable->getUserVoteEdgeType(),
$votable->getVotablePHID()); $votable->getVotablePHID());
@@ -77,7 +67,7 @@ final class PonderVoteEditor {
$votable->reload(); $votable->reload();
$curvote = (int)PhabricatorEdgeQuery::loadSingleEdgeData( $curvote = (int)PhabricatorEdgeQuery::loadSingleEdgeData(
$user->getPHID(), $actor->getPHID(),
$votable->getUserVoteEdgeType(), $votable->getUserVoteEdgeType(),
$votable->getVotablePHID()); $votable->getVotablePHID());

View File

@@ -49,7 +49,7 @@ final class PhabricatorProjectCreateController
$xactions[] = $xaction; $xactions[] = $xaction;
$editor = new PhabricatorProjectEditor($project); $editor = new PhabricatorProjectEditor($project);
$editor->setUser($user); $editor->setActor($user);
$editor->applyTransactions($xactions); $editor->applyTransactions($xactions);
} catch (PhabricatorProjectNameCollisionException $ex) { } catch (PhabricatorProjectNameCollisionException $ex) {
$e_name = 'Not Unique'; $e_name = 'Not Unique';

View File

@@ -80,7 +80,7 @@ final class PhabricatorProjectMembersEditController
if ($xactions) { if ($xactions) {
$editor = new PhabricatorProjectEditor($project); $editor = new PhabricatorProjectEditor($project);
$editor->setUser($user); $editor->setActor($user);
$editor->applyTransactions($xactions); $editor->applyTransactions($xactions);
} }

View File

@@ -92,7 +92,7 @@ final class PhabricatorProjectProfileEditController
$xactions[] = $xaction; $xactions[] = $xaction;
$editor = new PhabricatorProjectEditor($project); $editor = new PhabricatorProjectEditor($project);
$editor->setUser($user); $editor->setActor($user);
$editor->applyTransactions($xactions); $editor->applyTransactions($xactions);
} catch (PhabricatorProjectNameCollisionException $ex) { } catch (PhabricatorProjectNameCollisionException $ex) {
$e_name = 'Not Unique'; $e_name = 'Not Unique';

View File

@@ -16,10 +16,9 @@
* limitations under the License. * limitations under the License.
*/ */
final class PhabricatorProjectEditor { final class PhabricatorProjectEditor extends PhabricatorEditor {
private $project; private $project;
private $user;
private $projectName; private $projectName;
private $addEdges = array(); private $addEdges = array();
@@ -65,7 +64,7 @@ final class PhabricatorProjectEditor {
$xaction->setNewValue($new_value); $xaction->setNewValue($new_value);
$editor = new PhabricatorProjectEditor($project); $editor = new PhabricatorProjectEditor($project);
$editor->setUser($user); $editor->setActor($user);
$editor->applyTransactions(array($xaction)); $editor->applyTransactions(array($xaction));
} }
@@ -74,24 +73,16 @@ final class PhabricatorProjectEditor {
$this->project = $project; $this->project = $project;
} }
public function setUser(PhabricatorUser $user) {
$this->user = $user;
return $this;
}
public function applyTransactions(array $transactions) { public function applyTransactions(array $transactions) {
assert_instances_of($transactions, 'PhabricatorProjectTransaction'); assert_instances_of($transactions, 'PhabricatorProjectTransaction');
if (!$this->user) { $actor = $this->requireActor();
throw new Exception('Call setUser() before save()!');
}
$user = $this->user;
$project = $this->project; $project = $this->project;
$is_new = !$project->getID(); $is_new = !$project->getID();
if ($is_new) { if ($is_new) {
$project->setAuthorPHID($user->getPHID()); $project->setAuthorPHID($actor->getPHID());
} }
foreach ($transactions as $key => $xaction) { foreach ($transactions as $key => $xaction) {
@@ -105,7 +96,7 @@ final class PhabricatorProjectEditor {
if (!$is_new) { if (!$is_new) {
// You must be able to view a project in order to edit it in any capacity. // You must be able to view a project in order to edit it in any capacity.
PhabricatorPolicyFilter::requireCapability( PhabricatorPolicyFilter::requireCapability(
$user, $actor,
$project, $project,
PhabricatorPolicyCapability::CAN_VIEW); PhabricatorPolicyCapability::CAN_VIEW);
@@ -122,14 +113,14 @@ final class PhabricatorProjectEditor {
if ($need_edit) { if ($need_edit) {
PhabricatorPolicyFilter::requireCapability( PhabricatorPolicyFilter::requireCapability(
$user, $actor,
$project, $project,
PhabricatorPolicyCapability::CAN_EDIT); PhabricatorPolicyCapability::CAN_EDIT);
} }
if ($need_join) { if ($need_join) {
PhabricatorPolicyFilter::requireCapability( PhabricatorPolicyFilter::requireCapability(
$user, $actor,
$project, $project,
PhabricatorPolicyCapability::CAN_JOIN); PhabricatorPolicyCapability::CAN_JOIN);
} }
@@ -149,7 +140,7 @@ final class PhabricatorProjectEditor {
$edge_type = PhabricatorEdgeConfig::TYPE_PROJ_MEMBER; $edge_type = PhabricatorEdgeConfig::TYPE_PROJ_MEMBER;
$editor = new PhabricatorEdgeEditor(); $editor = new PhabricatorEdgeEditor();
$editor->setUser($this->user); $editor->setActor($actor);
foreach ($this->remEdges as $phid) { foreach ($this->remEdges as $phid) {
$editor->removeEdge($project->getPHID(), $edge_type, $phid); $editor->removeEdge($project->getPHID(), $edge_type, $phid);
} }
@@ -159,7 +150,7 @@ final class PhabricatorProjectEditor {
$editor->save(); $editor->save();
foreach ($transactions as $xaction) { foreach ($transactions as $xaction) {
$xaction->setAuthorPHID($user->getPHID()); $xaction->setAuthorPHID($actor->getPHID());
$xaction->setProjectID($project->getID()); $xaction->setProjectID($project->getID());
$xaction->save(); $xaction->save();
} }
@@ -278,7 +269,7 @@ final class PhabricatorProjectEditor {
// You can't edit away your ability to edit the project. // You can't edit away your ability to edit the project.
PhabricatorPolicyFilter::mustRetainCapability( PhabricatorPolicyFilter::mustRetainCapability(
$this->user, $this->getActor(),
$project, $project,
PhabricatorPolicyCapability::CAN_EDIT); PhabricatorPolicyCapability::CAN_EDIT);
break; break;
@@ -369,7 +360,7 @@ final class PhabricatorProjectEditor {
if (count($add) > 1) { if (count($add) > 1) {
return null; return null;
} else if (count($add) == 1) { } else if (count($add) == 1) {
if (reset($add) != $this->user->getPHID()) { if (reset($add) != $this->getActor()->getPHID()) {
return null; return null;
} else { } else {
return 'join'; return 'join';
@@ -379,7 +370,7 @@ final class PhabricatorProjectEditor {
if (count($rem) > 1) { if (count($rem) > 1) {
return null; return null;
} else if (count($rem) == 1) { } else if (count($rem) == 1) {
if (reset($rem) != $this->user->getPHID()) { if (reset($rem) != $this->getActor()->getPHID()) {
return null; return null;
} else { } else {
return 'leave'; return 'leave';

View File

@@ -114,7 +114,7 @@ final class PhabricatorProjectEditorTestCase extends PhabricatorTestCase {
$xaction->setNewValue($new_name); $xaction->setNewValue($new_name);
$editor = new PhabricatorProjectEditor($proj); $editor = new PhabricatorProjectEditor($proj);
$editor->setUser($user); $editor->setActor($user);
$editor->applyTransactions(array($xaction)); $editor->applyTransactions(array($xaction));
return true; return true;

View File

@@ -122,14 +122,16 @@ abstract class PhabricatorRepositoryCommitMessageParserWorker
$committer_phid, $committer_phid,
$author_phid, $author_phid,
$revision->getAuthorPHID()); $revision->getAuthorPHID());
$actor = id(new PhabricatorUser())
->loadOneWhere('phid = %s', $actor_phid);
$diff = $this->attachToRevision($revision, $actor_phid); $diff = $this->attachToRevision($revision, $actor_phid);
$revision->setDateCommitted($commit->getEpoch()); $revision->setDateCommitted($commit->getEpoch());
$editor = new DifferentialCommentEditor( $editor = new DifferentialCommentEditor(
$revision, $revision,
$actor_phid,
DifferentialAction::ACTION_CLOSE); DifferentialAction::ACTION_CLOSE);
$editor->setActor($actor);
$editor->setIsDaemonWorkflow(true); $editor->setIsDaemonWorkflow(true);
$vs_diff = $this->loadChangedByCommit($diff); $vs_diff = $this->loadChangedByCommit($diff);

View File

@@ -78,7 +78,7 @@ final class PhabricatorSearchAttachController
$rem_phids = array_diff($old_phids, $add_phids); $rem_phids = array_diff($old_phids, $add_phids);
$editor = id(new PhabricatorEdgeEditor()); $editor = id(new PhabricatorEdgeEditor());
$editor->setUser($user); $editor->setActor($user);
foreach ($add_phids as $phid) { foreach ($add_phids as $phid) {
$editor->addEdge($this->phid, $edge_type, $phid); $editor->addEdge($this->phid, $edge_type, $phid);
} }
@@ -159,6 +159,7 @@ final class PhabricatorSearchAttachController
} }
$editor = new ManiphestTransactionEditor(); $editor = new ManiphestTransactionEditor();
$editor->setActor($user);
$task_names = array(); $task_names = array();

View File

@@ -74,7 +74,7 @@ final class PhabricatorSubscriptionsEditController
} }
$editor = id(new PhabricatorSubscriptionsEditor()) $editor = id(new PhabricatorSubscriptionsEditor())
->setUser($user) ->setActor($user)
->setObject($object); ->setObject($object);
if ($is_add) { if ($is_add) {

View File

@@ -16,10 +16,9 @@
* limitations under the License. * limitations under the License.
*/ */
final class PhabricatorSubscriptionsEditor { final class PhabricatorSubscriptionsEditor extends PhabricatorEditor {
private $object; private $object;
private $user;
private $explicitSubscribePHIDs = array(); private $explicitSubscribePHIDs = array();
private $implicitSubscribePHIDs = array(); private $implicitSubscribePHIDs = array();
@@ -30,12 +29,6 @@ final class PhabricatorSubscriptionsEditor {
return $this; return $this;
} }
public function setUser(PhabricatorUser $user) {
$this->user = $user;
return $this;
}
/** /**
* Add explicit subscribers. These subscribers have explicitly subscribed * Add explicit subscribers. These subscribers have explicitly subscribed
* (or been subscribed) to the object, and will be added even if they * (or been subscribed) to the object, and will be added even if they
@@ -81,9 +74,7 @@ final class PhabricatorSubscriptionsEditor {
if (!$this->object) { if (!$this->object) {
throw new Exception('Call setObject() before save()!'); throw new Exception('Call setObject() before save()!');
} }
if (!$this->user) { $actor = $this->requireActor();
throw new Exception('Call setUser() before save()!');
}
$src = $this->object->getPHID(); $src = $this->object->getPHID();
@@ -109,7 +100,7 @@ final class PhabricatorSubscriptionsEditor {
$s_type = PhabricatorEdgeConfig::TYPE_OBJECT_HAS_SUBSCRIBER; $s_type = PhabricatorEdgeConfig::TYPE_OBJECT_HAS_SUBSCRIBER;
$editor = id(new PhabricatorEdgeEditor()) $editor = id(new PhabricatorEdgeEditor())
->setUser($this->user); ->setActor($actor);
foreach ($add as $phid => $ignored) { foreach ($add as $phid => $ignored) {
$editor->removeEdge($src, $u_type, $phid); $editor->removeEdge($src, $u_type, $phid);

View File

@@ -0,0 +1,47 @@
<?php
/*
* Copyright 2012 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
abstract class PhabricatorEditor {
private $actor;
private $excludeMailRecipientPHIDs = array();
final public function setActor(PhabricatorUser $user) {
$this->user = $user;
return $this;
}
final protected function getActor() {
return $this->user;
}
final protected function requireActor() {
$actor = $this->getActor();
if (!$actor) {
throw new Exception('You must setActor()!');
}
return $actor;
}
final public function setExcludeMailRecipientPHIDs($phids) {
$this->excludeMailRecipientPHIDs = $phids;
return $this;
}
final protected function getExcludeMailRecipientPHIDs() {
return $this->excludeMailRecipientPHIDs;
}
}

View File

@@ -37,7 +37,7 @@ final class PhabricatorEdgeTestCase extends PhabricatorTestCase {
$phid2 = $obj2->getPHID(); $phid2 = $obj2->getPHID();
$editor = id(new PhabricatorEdgeEditor()) $editor = id(new PhabricatorEdgeEditor())
->setUser($user) ->setActor($user)
->addEdge($phid1, PhabricatorEdgeConfig::TYPE_TEST_NO_CYCLE, $phid2) ->addEdge($phid1, PhabricatorEdgeConfig::TYPE_TEST_NO_CYCLE, $phid2)
->addEdge($phid2, PhabricatorEdgeConfig::TYPE_TEST_NO_CYCLE, $phid1); ->addEdge($phid2, PhabricatorEdgeConfig::TYPE_TEST_NO_CYCLE, $phid1);
@@ -57,12 +57,12 @@ final class PhabricatorEdgeTestCase extends PhabricatorTestCase {
// fail (it introduces a cycle). // fail (it introduces a cycle).
$editor = id(new PhabricatorEdgeEditor()) $editor = id(new PhabricatorEdgeEditor())
->setUser($user) ->setActor($user)
->addEdge($phid1, PhabricatorEdgeConfig::TYPE_TEST_NO_CYCLE, $phid2) ->addEdge($phid1, PhabricatorEdgeConfig::TYPE_TEST_NO_CYCLE, $phid2)
->save(); ->save();
$editor = id(new PhabricatorEdgeEditor()) $editor = id(new PhabricatorEdgeEditor())
->setUser($user) ->setActor($user)
->addEdge($phid2, PhabricatorEdgeConfig::TYPE_TEST_NO_CYCLE, $phid1); ->addEdge($phid2, PhabricatorEdgeConfig::TYPE_TEST_NO_CYCLE, $phid1);
$caught = null; $caught = null;

View File

@@ -28,26 +28,20 @@
* *
* id(new PhabricatorEdgeEditor()) * id(new PhabricatorEdgeEditor())
* ->addEdge($src, $type, $dst) * ->addEdge($src, $type, $dst)
* ->setUser($user) * ->setActor($user)
* ->save(); * ->save();
* *
* @task edit Editing Edges * @task edit Editing Edges
* @task cycles Cycle Prevention * @task cycles Cycle Prevention
* @task internal Internals * @task internal Internals
*/ */
final class PhabricatorEdgeEditor { final class PhabricatorEdgeEditor extends PhabricatorEditor {
private $addEdges = array(); private $addEdges = array();
private $remEdges = array(); private $remEdges = array();
private $openTransactions = array(); private $openTransactions = array();
private $user;
private $suppressEvents; private $suppressEvents;
public function setUser(PhabricatorUser $user) {
$this->user = $user;
return $this;
}
/* -( Editing Edges )------------------------------------------------------ */ /* -( Editing Edges )------------------------------------------------------ */
@@ -398,7 +392,7 @@ final class PhabricatorEdgeEditor {
'add' => $this->addEdges, 'add' => $this->addEdges,
'rem' => $this->remEdges, 'rem' => $this->remEdges,
)); ));
$event->setUser($this->user); $event->setUser($this->getActor());
PhutilEventEngine::dispatchEvent($event); PhutilEventEngine::dispatchEvent($event);
} }