/**
  * Returns 'join' if this transaction causes the acting user ONLY to join the
  * project.
  *
  * Returns 'leave' if this transaction causes the acting user ONLY to leave
  * the project.
  *
  * Returns null in all other cases.
  */
 private function isJoinOrLeaveTransaction(PhabricatorProjectTransaction $xaction)
 {
     $type = $xaction->getTransactionType();
     if ($type != PhabricatorProjectTransactionType::TYPE_MEMBERS) {
         return null;
     }
     switch ($type) {
         case PhabricatorProjectTransactionType::TYPE_MEMBERS:
             $old = $xaction->getOldValue();
             $new = $xaction->getNewValue();
             $add = array_diff($new, $old);
             $rem = array_diff($old, $new);
             if (count($add) > 1) {
                 return null;
             } else {
                 if (count($add) == 1) {
                     if (reset($add) != $this->user->getPHID()) {
                         return null;
                     } else {
                         return 'join';
                     }
                 }
             }
             if (count($rem) > 1) {
                 return null;
             } else {
                 if (count($rem) == 1) {
                     if (reset($rem) != $this->user->getPHID()) {
                         return null;
                     } else {
                         return 'leave';
                     }
                 }
             }
             break;
     }
     return true;
 }
 private function transactionHasEffect(PhabricatorProjectTransaction $xaction)
 {
     return $xaction->getOldValue() !== $xaction->getNewValue();
 }