@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

When predicting project membership during edits, predict milestones will have parent membership

Summary:
Depends on D20919. Ref T13462. When editing milestones, we currently predict they will have no members for policy evaluation purposes. This isn't the right rule.

Instead, predict that their membership will be the same as the parent project's membership, and pass this hint to the policy layer.

See T13462 for additional context and discussion.

Test Plan:
- Set project A's edit policy to "Project Members".
- Joined project A.
- Tried to create a milestone of project A.
- Before: policy exception that the edit policy excludes me.
- After: clean milestone creation.
- As a non-member, tried to create a milestone. Received appropriate policy error.

Maniphest Tasks: T13462

Differential Revision: https://secure.phabricator.com/D20920

+45 -26
+45 -26
src/applications/project/editor/PhabricatorProjectTransactionEditor.php
··· 345 345 $copy->setMilestoneNumber(1); 346 346 } 347 347 348 - $member_xaction = null; 349 - foreach ($xactions as $xaction) { 350 - if ($xaction->getTransactionType() !== $type_edge) { 351 - continue; 352 - } 348 + $hint = null; 349 + if ($this->getIsMilestone()) { 350 + // See T13462. If we're creating a milestone, predict that the members 351 + // of the newly created milestone will be the same as the members of the 352 + // parent project, since this is the governing rule. 353 353 354 - $edgetype = $xaction->getMetadataValue('edge:type'); 355 - if ($edgetype !== $edgetype_member) { 356 - continue; 354 + $parent = $copy->getParentProject(); 355 + 356 + $parent = id(new PhabricatorProjectQuery()) 357 + ->setViewer($this->getActor()) 358 + ->withPHIDs(array($parent->getPHID())) 359 + ->needMembers(true) 360 + ->executeOne(); 361 + $members = $parent->getMemberPHIDs(); 362 + 363 + $hint = array_fuse($members); 364 + } else { 365 + $member_xaction = null; 366 + foreach ($xactions as $xaction) { 367 + if ($xaction->getTransactionType() !== $type_edge) { 368 + continue; 369 + } 370 + 371 + $edgetype = $xaction->getMetadataValue('edge:type'); 372 + if ($edgetype !== $edgetype_member) { 373 + continue; 374 + } 375 + 376 + $member_xaction = $xaction; 357 377 } 358 378 359 - $member_xaction = $xaction; 360 - } 379 + if ($member_xaction) { 380 + $object_phid = $object->getPHID(); 361 381 362 - if ($member_xaction) { 363 - $object_phid = $object->getPHID(); 382 + if ($object_phid) { 383 + $project = id(new PhabricatorProjectQuery()) 384 + ->setViewer($this->getActor()) 385 + ->withPHIDs(array($object_phid)) 386 + ->needMembers(true) 387 + ->executeOne(); 388 + $members = $project->getMemberPHIDs(); 389 + } else { 390 + $members = array(); 391 + } 364 392 365 - if ($object_phid) { 366 - $project = id(new PhabricatorProjectQuery()) 367 - ->setViewer($this->getActor()) 368 - ->withPHIDs(array($object_phid)) 369 - ->needMembers(true) 370 - ->executeOne(); 371 - $members = $project->getMemberPHIDs(); 372 - } else { 373 - $members = array(); 393 + $clone_xaction = clone $member_xaction; 394 + $hint = $this->getPHIDTransactionNewValue($clone_xaction, $members); 395 + $hint = array_fuse($hint); 374 396 } 397 + } 375 398 376 - $clone_xaction = clone $member_xaction; 377 - $hint = $this->getPHIDTransactionNewValue($clone_xaction, $members); 399 + if ($hint !== null) { 378 400 $rule = new PhabricatorProjectMembersPolicyRule(); 379 - 380 - $hint = array_fuse($hint); 381 - 382 401 PhabricatorPolicyRule::passTransactionHintToRule( 383 402 $copy, 384 403 $rule,