コード例 #1
0
ファイル: PhameBlogQuery.php プロジェクト: rudimk/phabricator
 private function loadBloggers(array $blogs)
 {
     assert_instances_of($blogs, 'PhameBlog');
     $blog_phids = mpull($blogs, 'getPHID');
     $edge_types = array(PhabricatorEdgeConfig::TYPE_BLOG_HAS_BLOGGER);
     $query = new PhabricatorEdgeQuery();
     $query->withSourcePHIDs($blog_phids)->withEdgeTypes($edge_types)->execute();
     $all_blogger_phids = $query->getDestinationPHIDs($blog_phids, $edge_types);
     $handles = id(new PhabricatorObjectHandleData($all_blogger_phids))->loadHandles();
     foreach ($blogs as $blog) {
         $blogger_phids = $query->getDestinationPHIDs(array($blog->getPHID()), $edge_types);
         $blog->attachBloggers(array_select_keys($handles, $blogger_phids));
     }
 }
コード例 #2
0
 public static function loadForRevision($revision)
 {
     $app_legalpad = 'PhabricatorLegalpadApplication';
     if (!PhabricatorApplication::isClassInstalled($app_legalpad)) {
         return array();
     }
     if (!$revision->getPHID()) {
         return array();
     }
     $phids = PhabricatorEdgeQuery::loadDestinationPHIDs($revision->getPHID(), LegalpadObjectNeedsSignatureEdgeType::EDGECONST);
     if ($phids) {
         // NOTE: We're bypassing permissions to pull these. We have to expose
         // some information about signature status in order to implement this
         // field meaningfully (otherwise, we could not tell reviewers that they
         // can't accept the revision yet), but that's OK because the only way to
         // require signatures is with a "Global" Herald rule, which requires a
         // high level of access.
         $signatures = id(new LegalpadDocumentSignatureQuery())->setViewer(PhabricatorUser::getOmnipotentUser())->withDocumentPHIDs($phids)->withSignerPHIDs(array($revision->getAuthorPHID()))->execute();
         $signatures = mpull($signatures, null, 'getDocumentPHID');
         $phids = array_fuse($phids);
         foreach ($phids as $phid) {
             $phids[$phid] = isset($signatures[$phid]);
         }
     }
     return $phids;
 }
コード例 #3
0
 public function save()
 {
     if (!$this->object) {
         throw new Exception('Call setObject() before save()!');
     }
     $actor = $this->requireActor();
     $src = $this->object->getPHID();
     if ($this->implicitSubscribePHIDs) {
         $unsub = PhabricatorEdgeQuery::loadDestinationPHIDs($src, PhabricatorEdgeConfig::TYPE_OBJECT_HAS_UNSUBSCRIBER);
         $unsub = array_fill_keys($unsub, true);
         $this->implicitSubscribePHIDs = array_diff_key($this->implicitSubscribePHIDs, $unsub);
     }
     $add = $this->implicitSubscribePHIDs + $this->explicitSubscribePHIDs;
     $del = $this->unsubscribePHIDs;
     // If a PHID is marked for both subscription and unsubscription, treat
     // unsubscription as the stronger action.
     $add = array_diff_key($add, $del);
     if ($add || $del) {
         $u_type = PhabricatorEdgeConfig::TYPE_OBJECT_HAS_UNSUBSCRIBER;
         $s_type = PhabricatorEdgeConfig::TYPE_OBJECT_HAS_SUBSCRIBER;
         $editor = new PhabricatorEdgeEditor();
         foreach ($add as $phid => $ignored) {
             $editor->removeEdge($src, $u_type, $phid);
             $editor->addEdge($src, $s_type, $phid);
         }
         foreach ($del as $phid => $ignored) {
             $editor->removeEdge($src, $s_type, $phid);
             $editor->addEdge($src, $u_type, $phid);
         }
         $editor->save();
     }
 }
 private function performMerge(ManiphestTask $task, PhabricatorObjectHandle $handle, array $phids)
 {
     $user = $this->getRequest()->getUser();
     $response = id(new AphrontReloadResponse())->setURI($handle->getURI());
     $phids = array_fill_keys($phids, true);
     unset($phids[$task->getPHID()]);
     // Prevent merging a task into itself.
     if (!$phids) {
         return $response;
     }
     $targets = id(new ManiphestTaskQuery())->setViewer($user)->requireCapabilities(array(PhabricatorPolicyCapability::CAN_VIEW, PhabricatorPolicyCapability::CAN_EDIT))->withPHIDs(array_keys($phids))->needSubscriberPHIDs(true)->needProjectPHIDs(true)->execute();
     if (empty($targets)) {
         return $response;
     }
     $editor = id(new ManiphestTransactionEditor())->setActor($user)->setContentSourceFromRequest($this->getRequest())->setContinueOnNoEffect(true)->setContinueOnMissingFields(true);
     $cc_vector = array();
     // since we loaded this via a generic object query, go ahead and get the
     // attach the subscriber and project phids now
     $task->attachSubscriberPHIDs(PhabricatorSubscribersQuery::loadSubscribersForPHID($task->getPHID()));
     $task->attachProjectPHIDs(PhabricatorEdgeQuery::loadDestinationPHIDs($task->getPHID(), PhabricatorProjectObjectHasProjectEdgeType::EDGECONST));
     $cc_vector[] = $task->getSubscriberPHIDs();
     foreach ($targets as $target) {
         $cc_vector[] = $target->getSubscriberPHIDs();
         $cc_vector[] = array($target->getAuthorPHID(), $target->getOwnerPHID());
         $merged_into_txn = id(new ManiphestTransaction())->setTransactionType(ManiphestTransaction::TYPE_MERGED_INTO)->setNewValue($task->getPHID());
         $editor->applyTransactions($target, array($merged_into_txn));
     }
     $all_ccs = array_mergev($cc_vector);
     $all_ccs = array_filter($all_ccs);
     $all_ccs = array_unique($all_ccs);
     $add_ccs = id(new ManiphestTransaction())->setTransactionType(PhabricatorTransactions::TYPE_SUBSCRIBERS)->setNewValue(array('=' => $all_ccs));
     $merged_from_txn = id(new ManiphestTransaction())->setTransactionType(ManiphestTransaction::TYPE_MERGED_FROM)->setNewValue(mpull($targets, 'getPHID'));
     $editor->applyTransactions($task, array($add_ccs, $merged_from_txn));
     return $response;
 }
コード例 #5
0
 protected function readValueFromRevision(DifferentialRevision $revision)
 {
     if (!$revision->getPHID()) {
         return array();
     }
     return PhabricatorEdgeQuery::loadDestinationPHIDs($revision->getPHID(), DifferentialRevisionHasTaskEdgeType::EDGECONST);
 }
コード例 #6
0
 public function saveVote()
 {
     if (!$this->votable) {
         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;
     $newvote = $this->vote;
     // prepare vote add, or update if this user is amending an
     // earlier vote
     $editor = id(new PhabricatorEdgeEditor())->setUser($user)->addEdge($user->getPHID(), $votable->getUserVoteEdgeType(), $votable->getVotablePHID(), array('data' => $newvote))->removeEdge($user->getPHID(), $votable->getUserVoteEdgeType(), $votable->getVotablePHID());
     $conn = $votable->establishConnection('w');
     $trans = $conn->openTransaction();
     $trans->beginReadLocking();
     $votable->reload();
     $curvote = (int) PhabricatorEdgeQuery::loadSingleEdgeData($user->getPHID(), $votable->getUserVoteEdgeType(), $votable->getVotablePHID());
     if (!$curvote) {
         $curvote = PonderConstants::NONE_VOTE;
     }
     // adjust votable's score by this much
     $delta = $newvote - $curvote;
     queryfx($conn, 'UPDATE %T as t
     SET t.`voteCount` = t.`voteCount` + %d
     WHERE t.`PHID` = %s', $votable->getTableName(), $delta, $votable->getVotablePHID());
     $editor->save();
     $trans->endReadLocking();
     $trans->saveTransaction();
 }
コード例 #7
0
 protected function processDiffusionRequest(AphrontRequest $request)
 {
     $user = $request->getUser();
     $drequest = $this->getDiffusionRequest();
     $callsign = $drequest->getRepository()->getCallsign();
     $repository = $drequest->getRepository();
     $commit = $drequest->loadCommit();
     $data = $commit->loadCommitData();
     $page_title = pht('Edit Diffusion Commit');
     if (!$commit) {
         return new Aphront404Response();
     }
     $commit_phid = $commit->getPHID();
     $edge_type = PhabricatorProjectObjectHasProjectEdgeType::EDGECONST;
     $current_proj_phids = PhabricatorEdgeQuery::loadDestinationPHIDs($commit_phid, $edge_type);
     if ($request->isFormPost()) {
         $xactions = array();
         $proj_phids = $request->getArr('projects');
         $xactions[] = id(new PhabricatorAuditTransaction())->setTransactionType(PhabricatorTransactions::TYPE_EDGE)->setMetadataValue('edge:type', $edge_type)->setNewValue(array('=' => array_fuse($proj_phids)));
         $editor = id(new PhabricatorAuditEditor())->setActor($user)->setContinueOnNoEffect(true)->setContentSourceFromRequest($request);
         $xactions = $editor->applyTransactions($commit, $xactions);
         return id(new AphrontRedirectResponse())->setURI('/r' . $callsign . $commit->getCommitIdentifier());
     }
     $tokenizer_id = celerity_generate_unique_node_id();
     $form = id(new AphrontFormView())->setUser($user)->setAction($request->getRequestURI()->getPath())->appendControl(id(new AphrontFormTokenizerControl())->setLabel(pht('Projects'))->setName('projects')->setValue($current_proj_phids)->setID($tokenizer_id)->setCaption(javelin_tag('a', array('href' => '/project/create/', 'mustcapture' => true, 'sigil' => 'project-create'), pht('Create New Project')))->setDatasource(new PhabricatorProjectDatasource()));
     $reason = $data->getCommitDetail('autocloseReason', false);
     $reason = PhabricatorRepository::BECAUSE_AUTOCLOSE_FORCED;
     if ($reason !== false) {
         switch ($reason) {
             case PhabricatorRepository::BECAUSE_REPOSITORY_IMPORTING:
                 $desc = pht('No, Repository Importing');
                 break;
             case PhabricatorRepository::BECAUSE_AUTOCLOSE_DISABLED:
                 $desc = pht('No, Autoclose Disabled');
                 break;
             case PhabricatorRepository::BECAUSE_NOT_ON_AUTOCLOSE_BRANCH:
                 $desc = pht('No, Not On Autoclose Branch');
                 break;
             case PhabricatorRepository::BECAUSE_AUTOCLOSE_FORCED:
                 $desc = pht('Yes, Forced Via bin/repository CLI Tool.');
                 break;
             case null:
                 $desc = pht('Yes');
                 break;
             default:
                 $desc = pht('Unknown');
                 break;
         }
         $doc_href = PhabricatorEnv::getDoclink('Diffusion User Guide: Autoclose');
         $doc_link = phutil_tag('a', array('href' => $doc_href, 'target' => '_blank'), pht('Learn More'));
         $form->appendChild(id(new AphrontFormMarkupControl())->setLabel(pht('Autoclose?'))->setValue(array($desc, " · ", $doc_link)));
     }
     Javelin::initBehavior('project-create', array('tokenizerID' => $tokenizer_id));
     $submit = id(new AphrontFormSubmitControl())->setValue(pht('Save'))->addCancelButton('/r' . $callsign . $commit->getCommitIdentifier());
     $form->appendChild($submit);
     $crumbs = $this->buildCrumbs(array('commit' => true));
     $crumbs->addTextCrumb(pht('Edit'));
     $form_box = id(new PHUIObjectBoxView())->setHeaderText($page_title)->setForm($form);
     return $this->buildApplicationPage(array($crumbs, $form_box), array('title' => $page_title));
 }
コード例 #8
0
 protected function buildAbstractDocumentByPHID($phid)
 {
     $commit = $this->loadDocumentByPHID($phid);
     $commit_data = id(new PhabricatorRepositoryCommitData())->loadOneWhere('commitID = %d', $commit->getID());
     $date_created = $commit->getEpoch();
     $commit_message = $commit_data->getCommitMessage();
     $author_phid = $commit_data->getCommitDetail('authorPHID');
     $repository = id(new PhabricatorRepositoryQuery())->setViewer($this->getViewer())->withIDs(array($commit->getRepositoryID()))->executeOne();
     if (!$repository) {
         throw new Exception('No such repository!');
     }
     $title = 'r' . $repository->getCallsign() . $commit->getCommitIdentifier() . ' ' . $commit_data->getSummary();
     $doc = new PhabricatorSearchAbstractDocument();
     $doc->setPHID($commit->getPHID());
     $doc->setDocumentType(PhabricatorRepositoryCommitPHIDType::TYPECONST);
     $doc->setDocumentCreated($date_created);
     $doc->setDocumentModified($date_created);
     $doc->setDocumentTitle($title);
     $doc->addField(PhabricatorSearchField::FIELD_BODY, $commit_message);
     if ($author_phid) {
         $doc->addRelationship(PhabricatorSearchRelationship::RELATIONSHIP_AUTHOR, $author_phid, PhabricatorPeopleUserPHIDType::TYPECONST, $date_created);
     }
     $project_phids = PhabricatorEdgeQuery::loadDestinationPHIDs($commit->getPHID(), PhabricatorEdgeConfig::TYPE_COMMIT_HAS_PROJECT);
     if ($project_phids) {
         foreach ($project_phids as $project_phid) {
             $doc->addRelationship(PhabricatorSearchRelationship::RELATIONSHIP_PROJECT, $project_phid, PhabricatorProjectProjectPHIDType::TYPECONST, $date_created);
         }
     }
     $doc->addRelationship(PhabricatorSearchRelationship::RELATIONSHIP_REPOSITORY, $repository->getPHID(), PhabricatorRepositoryRepositoryPHIDType::TYPECONST, $date_created);
     $this->indexTransactions($doc, new PhabricatorAuditTransactionQuery(), array($commit->getPHID()));
     return $doc;
 }
コード例 #9
0
 protected function receiveEmail(PhabricatorMetaMTAReceivedMail $mail)
 {
     $conpherence = $this->getMailReceiver();
     $user = $this->getActor();
     if (!$conpherence->getPHID()) {
         $conpherence->attachParticipants(array())->attachFilePHIDs(array());
     } else {
         $edge_type = PhabricatorObjectHasFileEdgeType::EDGECONST;
         $file_phids = PhabricatorEdgeQuery::loadDestinationPHIDs($conpherence->getPHID(), $edge_type);
         $conpherence->attachFilePHIDs($file_phids);
         $participants = id(new ConpherenceParticipant())->loadAllWhere('conpherencePHID = %s', $conpherence->getPHID());
         $participants = mpull($participants, null, 'getParticipantPHID');
         $conpherence->attachParticipants($participants);
     }
     $content_source = PhabricatorContentSource::newForSource(PhabricatorContentSource::SOURCE_EMAIL, array('id' => $mail->getID()));
     $editor = id(new ConpherenceEditor())->setActor($user)->setContentSource($content_source)->setParentMessageID($mail->getMessageID());
     $body = $mail->getCleanTextBody();
     $body = $this->enhanceBodyWithAttachments($body, $mail->getAttachments());
     $xactions = array();
     if ($this->getMailAddedParticipantPHIDs()) {
         $xactions[] = id(new ConpherenceTransaction())->setTransactionType(ConpherenceTransaction::TYPE_PARTICIPANTS)->setNewValue(array('+' => $this->getMailAddedParticipantPHIDs()));
     }
     $xactions = array_merge($xactions, $editor->generateTransactionsFromText($user, $conpherence, $body));
     $editor->applyTransactions($conpherence, $xactions);
     return $conpherence;
 }
コード例 #10
0
 public function saveVote()
 {
     $actor = $this->requireActor();
     if (!$this->votable) {
         throw new PhutilInvalidStateException('setVotable');
     }
     $votable = $this->votable;
     $newvote = $this->vote;
     // prepare vote add, or update if this user is amending an
     // earlier vote
     $editor = id(new PhabricatorEdgeEditor())->addEdge($actor->getPHID(), $votable->getUserVoteEdgeType(), $votable->getVotablePHID(), array('data' => $newvote))->removeEdge($actor->getPHID(), $votable->getUserVoteEdgeType(), $votable->getVotablePHID());
     $conn = $votable->establishConnection('w');
     $trans = $conn->openTransaction();
     $trans->beginReadLocking();
     $votable->reload();
     $curvote = (int) PhabricatorEdgeQuery::loadSingleEdgeData($actor->getPHID(), $votable->getUserVoteEdgeType(), $votable->getVotablePHID());
     if (!$curvote) {
         $curvote = PonderVote::VOTE_NONE;
     }
     // Adjust votable's score by this much.
     $delta = $newvote - $curvote;
     queryfx($conn, 'UPDATE %T as t
     SET t.voteCount = t.voteCount + %d
     WHERE t.PHID = %s', $votable->getTableName(), $delta, $votable->getVotablePHID());
     $editor->save();
     $trans->endReadLocking();
     $trans->saveTransaction();
 }
コード例 #11
0
 public function save()
 {
     if (!$this->object) {
         throw new PhutilInvalidStateException('setObject');
     }
     $actor = $this->requireActor();
     $src = $this->object->getPHID();
     if ($this->implicitSubscribePHIDs) {
         $unsub = PhabricatorEdgeQuery::loadDestinationPHIDs($src, PhabricatorObjectHasUnsubscriberEdgeType::EDGECONST);
         $unsub = array_fill_keys($unsub, true);
         $this->implicitSubscribePHIDs = array_diff_key($this->implicitSubscribePHIDs, $unsub);
     }
     $add = $this->implicitSubscribePHIDs + $this->explicitSubscribePHIDs;
     $del = $this->unsubscribePHIDs;
     // If a PHID is marked for both subscription and unsubscription, treat
     // unsubscription as the stronger action.
     $add = array_diff_key($add, $del);
     if ($add || $del) {
         $u_type = PhabricatorObjectHasUnsubscriberEdgeType::EDGECONST;
         $s_type = PhabricatorObjectHasSubscriberEdgeType::EDGECONST;
         $editor = new PhabricatorEdgeEditor();
         foreach ($add as $phid => $ignored) {
             $editor->removeEdge($src, $u_type, $phid);
             $editor->addEdge($src, $s_type, $phid);
         }
         foreach ($del as $phid => $ignored) {
             $editor->removeEdge($src, $s_type, $phid);
             $editor->addEdge($src, $u_type, $phid);
         }
         $editor->save();
     }
 }
コード例 #12
0
 private function handleHovercardEvent($event)
 {
     $viewer = $event->getUser();
     $hovercard = $event->getValue('hovercard');
     $object_handle = $event->getValue('handle');
     $commit = $event->getValue('object');
     if (!$commit instanceof PhabricatorRepositoryCommit) {
         return;
     }
     $commit_data = $commit->loadCommitData();
     $revision = PhabricatorEdgeQuery::loadDestinationPHIDs($commit->getPHID(), PhabricatorEdgeConfig::TYPE_COMMIT_HAS_DREV);
     $revision = reset($revision);
     $author = $commit->getAuthorPHID();
     $phids = array_filter(array($revision, $author));
     $handles = id(new PhabricatorHandleQuery())->setViewer($viewer)->withPHIDs($phids)->execute();
     if ($author) {
         $author = $handles[$author]->renderLink();
     } else {
         $author = phutil_tag('em', array(), $commit_data->getAuthorName());
     }
     $hovercard->setTitle($object_handle->getName());
     $hovercard->setDetail($commit->getSummary());
     $hovercard->addField(pht('Author'), $author);
     $hovercard->addField(pht('Date'), phabricator_date($commit->getEpoch(), $viewer));
     if ($commit->getAuditStatus() != PhabricatorAuditCommitStatusConstants::NONE) {
         $hovercard->addField(pht('Audit Status'), PhabricatorAuditCommitStatusConstants::getStatusName($commit->getAuditStatus()));
     }
     if ($revision) {
         $rev_handle = $handles[$revision];
         $hovercard->addField(pht('Revision'), $rev_handle->renderLink());
     }
     $event->setValue('hovercard', $hovercard);
 }
コード例 #13
0
 public function processRequest()
 {
     $request = $this->getRequest();
     $user = $request->getUser();
     if ($this->id) {
         $question = id(new PonderQuestionQuery())->setViewer($user)->withIDs(array($this->id))->requireCapabilities(array(PhabricatorPolicyCapability::CAN_VIEW, PhabricatorPolicyCapability::CAN_EDIT))->executeOne();
         if (!$question) {
             return new Aphront404Response();
         }
         $v_projects = PhabricatorEdgeQuery::loadDestinationPHIDs($question->getPHID(), PhabricatorProjectObjectHasProjectEdgeType::EDGECONST);
         $v_projects = array_reverse($v_projects);
     } else {
         $question = id(new PonderQuestion())->setStatus(PonderQuestionStatus::STATUS_OPEN)->setAuthorPHID($user->getPHID())->setVoteCount(0)->setAnswerCount(0)->setHeat(0.0);
         $v_projects = array();
     }
     $v_title = $question->getTitle();
     $v_content = $question->getContent();
     $errors = array();
     $e_title = true;
     if ($request->isFormPost()) {
         $v_title = $request->getStr('title');
         $v_content = $request->getStr('content');
         $v_projects = $request->getArr('projects');
         $len = phutil_utf8_strlen($v_title);
         if ($len < 1) {
             $errors[] = pht('Title must not be empty.');
             $e_title = pht('Required');
         } else {
             if ($len > 255) {
                 $errors[] = pht('Title is too long.');
                 $e_title = pht('Too Long');
             }
         }
         if (!$errors) {
             $template = id(new PonderQuestionTransaction());
             $xactions = array();
             $xactions[] = id(clone $template)->setTransactionType(PonderQuestionTransaction::TYPE_TITLE)->setNewValue($v_title);
             $xactions[] = id(clone $template)->setTransactionType(PonderQuestionTransaction::TYPE_CONTENT)->setNewValue($v_content);
             $proj_edge_type = PhabricatorProjectObjectHasProjectEdgeType::EDGECONST;
             $xactions[] = id(new PonderQuestionTransaction())->setTransactionType(PhabricatorTransactions::TYPE_EDGE)->setMetadataValue('edge:type', $proj_edge_type)->setNewValue(array('=' => array_fuse($v_projects)));
             $editor = id(new PonderQuestionEditor())->setActor($user)->setContentSourceFromRequest($request)->setContinueOnNoEffect(true);
             $editor->applyTransactions($question, $xactions);
             return id(new AphrontRedirectResponse())->setURI('/Q' . $question->getID());
         }
     }
     $form = id(new AphrontFormView())->setUser($user)->appendChild(id(new AphrontFormTextControl())->setLabel(pht('Question'))->setName('title')->setValue($v_title)->setError($e_title))->appendChild(id(new PhabricatorRemarkupControl())->setUser($user)->setName('content')->setID('content')->setValue($v_content)->setLabel(pht('Description'))->setUser($user));
     $form->appendControl(id(new AphrontFormTokenizerControl())->setLabel(pht('Projects'))->setName('projects')->setValue($v_projects)->setDatasource(new PhabricatorProjectDatasource()));
     $form->appendChild(id(new AphrontFormSubmitControl())->addCancelButton($this->getApplicationURI())->setValue(pht('Ask Away!')));
     $preview = id(new PHUIRemarkupPreviewPanel())->setHeader(pht('Question Preview'))->setControlID('content')->setPreviewURI($this->getApplicationURI('preview/'));
     $form_box = id(new PHUIObjectBoxView())->setHeaderText(pht('Ask New Question'))->setFormErrors($errors)->setForm($form);
     $crumbs = $this->buildApplicationCrumbs();
     $id = $question->getID();
     if ($id) {
         $crumbs->addTextCrumb("Q{$id}", "/Q{$id}");
         $crumbs->addTextCrumb(pht('Edit'));
     } else {
         $crumbs->addTextCrumb(pht('Ask Question'));
     }
     return $this->buildApplicationPage(array($crumbs, $form_box, $preview), array('title' => pht('Ask New Question')));
 }
 public function getHeraldFieldValue($object)
 {
     $repository = $this->getAdapter()->loadRepository();
     if (!$repository) {
         return array();
     }
     return PhabricatorEdgeQuery::loadDestinationPHIDs($repository->getPHID(), PhabricatorProjectObjectHasProjectEdgeType::EDGECONST);
 }
コード例 #15
0
 private function getDependentRevisionPHIDs()
 {
     $requested_object = $this->getObject()->getRequestedObjectPHID();
     if (!$requested_object instanceof DifferentialRevision) {
         return array();
     }
     $revision = $requested_object;
     return PhabricatorEdgeQuery::loadDestinationPHIDs($revision->getPHID(), DifferentialRevisionDependsOnRevisionEdgeType::EDGECONST);
 }
コード例 #16
0
 private function getDependentRevisionPHIDs()
 {
     $requested_object = $this->getObject()->getRequestedObjectPHID();
     if (!$requested_object instanceof DifferentialRevision) {
         return array();
     }
     $revision = $requested_object;
     return PhabricatorEdgeQuery::loadDestinationPHIDs($revision->getPHID(), PhabricatorEdgeConfig::TYPE_DREV_DEPENDS_ON_DREV);
 }
コード例 #17
0
 public function execute()
 {
     $query = new PhabricatorEdgeQuery();
     $edge_type = PhabricatorEdgeConfig::TYPE_OBJECT_HAS_SUBSCRIBER;
     $query->withSourcePHIDs($this->objectPHIDs);
     $query->withEdgeTypes(array($edge_type));
     if ($this->subscriberPHIDs) {
         $query->withDestinationPHIDs($this->subscriberPHIDs);
     }
     $edges = $query->execute();
     $results = array_fill_keys($this->objectPHIDs, array());
     foreach ($edges as $src => $edge_types) {
         foreach ($edge_types[$edge_type] as $dst => $data) {
             $results[$src][] = $dst;
         }
     }
     return $results;
 }
コード例 #18
0
 public function handleRequest(AphrontRequest $request)
 {
     $response = $this->loadDiffusionContextForEdit();
     if ($response) {
         return $response;
     }
     $viewer = $request->getUser();
     $drequest = $this->getDiffusionRequest();
     $repository = $drequest->getRepository();
     $edit_uri = $this->getRepositoryControllerURI($repository, 'edit/');
     $v_name = $repository->getName();
     $v_desc = $repository->getDetail('description');
     $v_slug = $repository->getRepositorySlug();
     $v_projects = PhabricatorEdgeQuery::loadDestinationPHIDs($repository->getPHID(), PhabricatorProjectObjectHasProjectEdgeType::EDGECONST);
     $e_name = true;
     $e_slug = null;
     $errors = array();
     $validation_exception = null;
     if ($request->isFormPost()) {
         $v_name = $request->getStr('name');
         $v_desc = $request->getStr('description');
         $v_projects = $request->getArr('projectPHIDs');
         $v_slug = $request->getStr('slug');
         if (!strlen($v_name)) {
             $e_name = pht('Required');
             $errors[] = pht('Repository name is required.');
         } else {
             $e_name = null;
         }
         if (!$errors) {
             $xactions = array();
             $template = id(new PhabricatorRepositoryTransaction());
             $type_name = PhabricatorRepositoryTransaction::TYPE_NAME;
             $type_desc = PhabricatorRepositoryTransaction::TYPE_DESCRIPTION;
             $type_edge = PhabricatorTransactions::TYPE_EDGE;
             $type_slug = PhabricatorRepositoryTransaction::TYPE_SLUG;
             $xactions[] = id(clone $template)->setTransactionType($type_name)->setNewValue($v_name);
             $xactions[] = id(clone $template)->setTransactionType($type_desc)->setNewValue($v_desc);
             $xactions[] = id(clone $template)->setTransactionType($type_slug)->setNewValue($v_slug);
             $xactions[] = id(clone $template)->setTransactionType($type_edge)->setMetadataValue('edge:type', PhabricatorProjectObjectHasProjectEdgeType::EDGECONST)->setNewValue(array('=' => array_fuse($v_projects)));
             $editor = id(new PhabricatorRepositoryEditor())->setContinueOnNoEffect(true)->setContentSourceFromRequest($request)->setActor($viewer);
             try {
                 $editor->applyTransactions($repository, $xactions);
                 return id(new AphrontRedirectResponse())->setURI($edit_uri);
             } catch (PhabricatorApplicationTransactionValidationException $ex) {
                 $validation_exception = $ex;
                 $e_slug = $ex->getShortMessage($type_slug);
             }
         }
     }
     $crumbs = $this->buildApplicationCrumbs();
     $crumbs->addTextCrumb(pht('Edit Basics'));
     $title = pht('Edit %s', $repository->getName());
     $form = id(new AphrontFormView())->setUser($viewer)->appendChild(id(new AphrontFormTextControl())->setName('name')->setLabel(pht('Name'))->setValue($v_name)->setError($e_name))->appendChild(id(new AphrontFormTextControl())->setName('slug')->setLabel(pht('Short Name'))->setValue($v_slug)->setError($e_slug))->appendChild(id(new PhabricatorRemarkupControl())->setUser($viewer)->setName('description')->setLabel(pht('Description'))->setValue($v_desc))->appendControl(id(new AphrontFormTokenizerControl())->setDatasource(new PhabricatorProjectDatasource())->setName('projectPHIDs')->setLabel(pht('Projects'))->setValue($v_projects))->appendChild(id(new AphrontFormSubmitControl())->setValue(pht('Save'))->addCancelButton($edit_uri))->appendChild(id(new PHUIFormDividerControl()))->appendRemarkupInstructions($this->getReadmeInstructions());
     $object_box = id(new PHUIObjectBoxView())->setHeaderText($title)->setValidationException($validation_exception)->setForm($form)->setFormErrors($errors);
     return $this->newPage()->setTitle($title)->setCrumbs($crumbs)->appendChild($object_box);
 }
コード例 #19
0
 protected function readValueFromRevision(DifferentialRevision $revision)
 {
     if (!$revision->getPHID()) {
         return array();
     }
     $projects = PhabricatorEdgeQuery::loadDestinationPHIDs($revision->getPHID(), PhabricatorProjectObjectHasProjectEdgeType::EDGECONST);
     $projects = array_reverse($projects);
     return $projects;
 }
コード例 #20
0
 private function handlePropertyEvent($event)
 {
     $user = $event->getUser();
     $object = $event->getValue('object');
     if (!$object || !$object->getPHID()) {
         // No object, or the object has no PHID yet..
         return;
     }
     if (!$object instanceof PhabricatorProjectInterface) {
         // This object doesn't have projects.
         return;
     }
     $project_phids = PhabricatorEdgeQuery::loadDestinationPHIDs($object->getPHID(), PhabricatorProjectObjectHasProjectEdgeType::EDGECONST);
     if ($project_phids) {
         $project_phids = array_reverse($project_phids);
         $handles = id(new PhabricatorHandleQuery())->setViewer($user)->withPHIDs($project_phids)->execute();
     } else {
         $handles = array();
     }
     // If this object can appear on boards, build the workboard annotations.
     // Some day, this might be a generic interface. For now, only tasks can
     // appear on boards.
     $can_appear_on_boards = $object instanceof ManiphestTask;
     $annotations = array();
     if ($handles && $can_appear_on_boards) {
         // TDOO: Generalize this UI and move it out of Maniphest.
         require_celerity_resource('maniphest-task-summary-css');
         $positions_query = id(new PhabricatorProjectColumnPositionQuery())->setViewer($user)->withBoardPHIDs($project_phids)->withObjectPHIDs(array($object->getPHID()))->needColumns(true);
         // This is important because positions will be created "on demand"
         // based on the set of columns. If we don't specify it, positions
         // won't be created.
         $columns = id(new PhabricatorProjectColumnQuery())->setViewer($user)->withProjectPHIDs($project_phids)->execute();
         if ($columns) {
             $positions_query->withColumns($columns);
         }
         $positions = $positions_query->execute();
         $positions = mpull($positions, null, 'getBoardPHID');
         foreach ($project_phids as $project_phid) {
             $handle = $handles[$project_phid];
             $position = idx($positions, $project_phid);
             if ($position) {
                 $column = $position->getColumn();
                 $column_name = pht('(%s)', $column->getDisplayName());
                 $column_link = phutil_tag('a', array('href' => $handle->getURI() . 'board/', 'class' => 'maniphest-board-link'), $column_name);
                 $annotations[$project_phid] = array(' ', $column_link);
             }
         }
     }
     if ($handles) {
         $list = id(new PHUIHandleTagListView())->setHandles($handles)->setAnnotations($annotations);
     } else {
         $list = phutil_tag('em', array(), pht('None'));
     }
     $view = $event->getValue('view');
     $view->addProperty(pht('Projects'), $list);
 }
コード例 #21
0
 protected function indexProjects(PhabricatorSearchAbstractDocument $doc, PhabricatorProjectInterface $object)
 {
     $project_phids = PhabricatorEdgeQuery::loadDestinationPHIDs($object->getPHID(), PhabricatorProjectObjectHasProjectEdgeType::EDGECONST);
     if ($project_phids) {
         foreach ($project_phids as $project_phid) {
             $doc->addRelationship(PhabricatorSearchRelationship::RELATIONSHIP_PROJECT, $project_phid, PhabricatorProjectProjectPHIDType::TYPECONST, $doc->getDocumentModified());
             // Bogus timestamp.
         }
     }
 }
コード例 #22
0
 public function fromPartial($partial_string)
 {
     $this->objectPHID = null;
     // Look for diffs
     $matches = array();
     if (preg_match('/^D([1-9]\\d*)$/', $partial_string, $matches)) {
         $diff_id = $matches[1];
         $diff_rev = id(new DifferentialRevisionQuery())->setViewer($this->getUser())->withIDs(array($diff_id))->needCommitPHIDs(true)->executeOne();
         if (!$diff_rev) {
             throw new ReleephCommitFinderException(pht('%s does not refer to an existing diff.', $partial_string));
         }
         $commit_phids = $diff_rev->getCommitPHIDs();
         if (!$commit_phids) {
             throw new ReleephCommitFinderException(pht('%s has no commits associated with it yet.', $partial_string));
         }
         $this->objectPHID = $diff_rev->getPHID();
         $commits = id(new DiffusionCommitQuery())->setViewer($this->getUser())->withPHIDs($commit_phids)->execute();
         $commits = msort($commits, 'getEpoch');
         return head($commits);
     }
     // Look for a raw commit number, or r<callsign><commit-number>.
     $repository = $this->releephProject->getRepository();
     $dr_data = null;
     $matches = array();
     if (preg_match('/^r(?P<callsign>[A-Z]+)(?P<commit>\\w+)$/', $partial_string, $matches)) {
         $callsign = $matches['callsign'];
         if ($callsign != $repository->getCallsign()) {
             throw new ReleephCommitFinderException(pht('%s is in a different repository to this Releeph project (%s).', $partial_string, $repository->getCallsign()));
         } else {
             $dr_data = $matches;
         }
     } else {
         $dr_data = array('callsign' => $repository->getCallsign(), 'commit' => $partial_string);
     }
     try {
         $dr_data['user'] = $this->getUser();
         $dr = DiffusionRequest::newFromDictionary($dr_data);
     } catch (Exception $ex) {
         $message = pht('No commit matches %s: %s', $partial_string, $ex->getMessage());
         throw new ReleephCommitFinderException($message);
     }
     $phabricator_repository_commit = $dr->loadCommit();
     if (!$phabricator_repository_commit) {
         throw new ReleephCommitFinderException(pht("The commit %s doesn't exist in this repository.", $partial_string));
     }
     // When requesting a single commit, if it has an associated review we
     // imply the review was requested instead. This is always correct for now
     // and consistent with the older behavior, although it might not be the
     // right rule in the future.
     $phids = PhabricatorEdgeQuery::loadDestinationPHIDs($phabricator_repository_commit->getPHID(), DiffusionCommitHasRevisionEdgeType::EDGECONST);
     if ($phids) {
         $this->objectPHID = head($phids);
     }
     return $phabricator_repository_commit;
 }
コード例 #23
0
 public function fromPartial($partial_string)
 {
     $this->objectPHID = null;
     // Look for diffs
     $matches = array();
     if (preg_match('/^D([1-9]\\d*)$/', $partial_string, $matches)) {
         $diff_id = $matches[1];
         // TOOD: (T603) This is all slated for annihilation.
         $diff_rev = id(new DifferentialRevision())->load($diff_id);
         if (!$diff_rev) {
             throw new ReleephCommitFinderException("{$partial_string} does not refer to an existing diff.");
         }
         $commit_phids = $diff_rev->loadCommitPHIDs();
         if (!$commit_phids) {
             throw new ReleephCommitFinderException("{$partial_string} has no commits associated with it yet.");
         }
         $this->objectPHID = $diff_rev->getPHID();
         $commits = id(new PhabricatorRepositoryCommit())->loadAllWhere('phid IN (%Ls) ORDER BY epoch ASC', $commit_phids);
         return head($commits);
     }
     // Look for a raw commit number, or r<callsign><commit-number>.
     $repository = $this->releephProject->getRepository();
     $dr_data = null;
     $matches = array();
     if (preg_match('/^r(?P<callsign>[A-Z]+)(?P<commit>\\w+)$/', $partial_string, $matches)) {
         $callsign = $matches['callsign'];
         if ($callsign != $repository->getCallsign()) {
             throw new ReleephCommitFinderException(sprintf('%s is in a different repository to this Releeph project (%s).', $partial_string, $repository->getCallsign()));
         } else {
             $dr_data = $matches;
         }
     } else {
         $dr_data = array('callsign' => $repository->getCallsign(), 'commit' => $partial_string);
     }
     try {
         $dr_data['user'] = $this->getUser();
         $dr = DiffusionRequest::newFromDictionary($dr_data);
     } catch (Exception $ex) {
         $message = "No commit matches {$partial_string}: " . $ex->getMessage();
         throw new ReleephCommitFinderException($message);
     }
     $phabricator_repository_commit = $dr->loadCommit();
     if (!$phabricator_repository_commit) {
         throw new ReleephCommitFinderException("The commit {$partial_string} doesn't exist in this repository.");
     }
     // When requesting a single commit, if it has an associated review we
     // imply the review was requested instead. This is always correct for now
     // and consistent with the older behavior, although it might not be the
     // right rule in the future.
     $phids = PhabricatorEdgeQuery::loadDestinationPHIDs($phabricator_repository_commit->getPHID(), PhabricatorEdgeConfig::TYPE_COMMIT_HAS_DREV);
     if ($phids) {
         $this->objectPHID = head($phids);
     }
     return $phabricator_repository_commit;
 }
コード例 #24
0
 /**
  * Publishes stories into JIRA using the JIRA API.
  */
 protected function publishFeedStory()
 {
     $story = $this->getFeedStory();
     $viewer = $this->getViewer();
     $provider = $this->getProvider();
     $object = $this->getStoryObject();
     $publisher = $this->getPublisher();
     $jira_issue_phids = PhabricatorEdgeQuery::loadDestinationPHIDs($object->getPHID(), PhabricatorJiraIssueHasObjectEdgeType::EDGECONST);
     if (!$jira_issue_phids) {
         $this->log("%s\n", pht('Story is about an object with no linked JIRA issues.'));
         return;
     }
     $do_anything = $this->shouldPostComment() || $this->shouldPostLink();
     if (!$do_anything) {
         $this->log("%s\n", pht('JIRA integration is configured not to post anything.'));
         return;
     }
     $xobjs = id(new DoorkeeperExternalObjectQuery())->setViewer($viewer)->withPHIDs($jira_issue_phids)->execute();
     if (!$xobjs) {
         $this->log("%s\n", pht('Story object has no corresponding external JIRA objects.'));
         return;
     }
     $try_users = $this->findUsersToPossess();
     if (!$try_users) {
         $this->log("%s\n", pht('No users to act on linked JIRA objects.'));
         return;
     }
     $xobjs = mgroup($xobjs, 'getApplicationDomain');
     foreach ($xobjs as $domain => $xobj_list) {
         $accounts = id(new PhabricatorExternalAccountQuery())->setViewer($viewer)->withUserPHIDs($try_users)->withAccountTypes(array($provider->getProviderType()))->withAccountDomains(array($domain))->requireCapabilities(array(PhabricatorPolicyCapability::CAN_VIEW, PhabricatorPolicyCapability::CAN_EDIT))->execute();
         // Reorder accounts in the original order.
         // TODO: This needs to be adjusted if/when we allow you to link multiple
         // accounts.
         $accounts = mpull($accounts, null, 'getUserPHID');
         $accounts = array_select_keys($accounts, $try_users);
         foreach ($xobj_list as $xobj) {
             foreach ($accounts as $account) {
                 try {
                     $jira_key = $xobj->getObjectID();
                     if ($this->shouldPostComment()) {
                         $this->postComment($account, $jira_key);
                     }
                     if ($this->shouldPostLink()) {
                         $this->postLink($account, $jira_key);
                     }
                     break;
                 } catch (HTTPFutureResponseStatus $ex) {
                     phlog($ex);
                     $this->log("%s\n", pht('Failed to update object %s using user %s.', $xobj->getObjectID(), $account->getUserPHID()));
                 }
             }
         }
     }
 }
コード例 #25
0
ファイル: PhameBlog.php プロジェクト: rudimk/phabricator
 public function loadBloggerPHIDs()
 {
     if (!$this->getPHID()) {
         return $this;
     }
     if ($this->bloggerPHIDs) {
         return $this;
     }
     $this->bloggerPHIDs = PhabricatorEdgeQuery::loadDestinationPHIDs($this->getPHID(), PhabricatorEdgeConfig::TYPE_BLOG_HAS_BLOGGER);
     return $this;
 }
コード例 #26
0
 public function processRequest()
 {
     $user = $this->getRequest()->getUser();
     $phid = $user->getPHID();
     $blog_phids = PhabricatorEdgeQuery::loadDestinationPHIDs($phid, PhabricatorEdgeConfig::TYPE_BLOGGER_HAS_BLOG);
     $blogs = id(new PhameBlogQuery())->withPHIDs($blog_phids)->needBloggers(true)->executeWithPager($this->getPager());
     $this->setBlogs($blogs);
     $this->setPageTitle('My Blogs');
     $this->setShowSideNav(true);
     return $this->buildBlogListPageResponse();
 }
 public function indexFulltextObject($object, PhabricatorSearchAbstractDocument $document)
 {
     $project_phids = PhabricatorEdgeQuery::loadDestinationPHIDs($object->getPHID(), PhabricatorProjectObjectHasProjectEdgeType::EDGECONST);
     if (!$project_phids) {
         return;
     }
     foreach ($project_phids as $project_phid) {
         $document->addRelationship(PhabricatorSearchRelationship::RELATIONSHIP_PROJECT, $project_phid, PhabricatorProjectProjectPHIDType::TYPECONST, $document->getDocumentModified());
         // Bogus timestamp.
     }
 }
コード例 #28
0
 public function processRequest()
 {
     $request = $this->getRequest();
     $user = $request->getUser();
     $handle = id(new PhabricatorHandleQuery())->setViewer($user)->withPHIDs(array($this->phid))->executeOne();
     $object_type = $handle->getType();
     $attach_type = $this->type;
     $object = id(new PhabricatorObjectQuery())->setViewer($user)->withPHIDs(array($this->phid))->executeOne();
     if (!$object) {
         return new Aphront404Response();
     }
     $edge_type = null;
     switch ($this->action) {
         case self::ACTION_EDGE:
         case self::ACTION_DEPENDENCIES:
         case self::ACTION_BLOCKS:
         case self::ACTION_ATTACH:
             $edge_type = $this->getEdgeType($object_type, $attach_type);
             break;
     }
     if ($request->isFormPost()) {
         $phids = explode(';', $request->getStr('phids'));
         $phids = array_filter($phids);
         $phids = array_values($phids);
         if ($edge_type) {
             if (!$object instanceof PhabricatorApplicationTransactionInterface) {
                 throw new Exception(pht('Expected object ("%s") to implement interface "%s".', get_class($object), 'PhabricatorApplicationTransactionInterface'));
             }
             $old_phids = PhabricatorEdgeQuery::loadDestinationPHIDs($this->phid, $edge_type);
             $add_phids = $phids;
             $rem_phids = array_diff($old_phids, $add_phids);
             $txn_editor = $object->getApplicationTransactionEditor()->setActor($user)->setContentSourceFromRequest($request)->setContinueOnMissingFields(true);
             $txn_template = $object->getApplicationTransactionTemplate()->setTransactionType(PhabricatorTransactions::TYPE_EDGE)->setMetadataValue('edge:type', $edge_type)->setNewValue(array('+' => array_fuse($add_phids), '-' => array_fuse($rem_phids)));
             $txn_editor->applyTransactions($object->getApplicationTransactionObject(), array($txn_template));
             return id(new AphrontReloadResponse())->setURI($handle->getURI());
         } else {
             return $this->performMerge($object, $handle, $phids);
         }
     } else {
         if ($edge_type) {
             $phids = PhabricatorEdgeQuery::loadDestinationPHIDs($this->phid, $edge_type);
         } else {
             // This is a merge.
             $phids = array();
         }
     }
     $strings = $this->getStrings();
     $handles = $this->loadViewerHandles($phids);
     $obj_dialog = new PhabricatorObjectSelectorDialog();
     $obj_dialog->setUser($user)->setHandles($handles)->setFilters($this->getFilters($strings))->setSelectedFilter($strings['selected'])->setExcluded($this->phid)->setCancelURI($handle->getURI())->setSearchURI('/search/select/' . $attach_type . '/')->setTitle($strings['title'])->setHeader($strings['header'])->setButtonText($strings['button'])->setInstructions($strings['instructions']);
     $dialog = $obj_dialog->buildDialog();
     return id(new AphrontDialogResponse())->setDialog($dialog);
 }
コード例 #29
0
 private function handlePropertyEvent($event)
 {
     $user = $event->getUser();
     $object = $event->getValue('object');
     if (!$object || !$object->getPHID()) {
         // No object, or the object has no PHID yet..
         return;
     }
     if (!$object instanceof PhabricatorProjectInterface) {
         // This object doesn't have projects.
         return;
     }
     $project_phids = PhabricatorEdgeQuery::loadDestinationPHIDs($object->getPHID(), PhabricatorProjectObjectHasProjectEdgeType::EDGECONST);
     if ($project_phids) {
         $project_phids = array_reverse($project_phids);
         $handles = id(new PhabricatorHandleQuery())->setViewer($user)->withPHIDs($project_phids)->execute();
     } else {
         $handles = array();
     }
     // If this object can appear on boards, build the workboard annotations.
     // Some day, this might be a generic interface. For now, only tasks can
     // appear on boards.
     $can_appear_on_boards = $object instanceof ManiphestTask;
     $annotations = array();
     if ($handles && $can_appear_on_boards) {
         $engine = id(new PhabricatorBoardLayoutEngine())->setViewer($user)->setBoardPHIDs($project_phids)->setObjectPHIDs(array($object->getPHID()))->executeLayout();
         // TDOO: Generalize this UI and move it out of Maniphest.
         require_celerity_resource('maniphest-task-summary-css');
         foreach ($project_phids as $project_phid) {
             $handle = $handles[$project_phid];
             $columns = $engine->getObjectColumns($project_phid, $object->getPHID());
             $annotation = array();
             foreach ($columns as $column) {
                 $project_id = $column->getProject()->getID();
                 $column_name = pht('(%s)', $column->getDisplayName());
                 $column_link = phutil_tag('a', array('href' => "/project/board/{$project_id}/", 'class' => 'maniphest-board-link'), $column_name);
                 $annotation[] = $column_link;
             }
             if ($annotation) {
                 $annotations[$project_phid] = array(' ', phutil_implode_html(', ', $annotation));
             }
         }
     }
     if ($handles) {
         $list = id(new PHUIHandleTagListView())->setHandles($handles)->setAnnotations($annotations)->setShowHovercards(true);
     } else {
         $list = phutil_tag('em', array(), pht('None'));
     }
     $view = $event->getValue('view');
     $view->addProperty(pht('Projects'), $list);
 }
コード例 #30
0
 public function buildCustomEditFields(PhabricatorEditEngine $engine, PhabricatorApplicationTransactionInterface $object)
 {
     $edge_type = PhabricatorTransactions::TYPE_EDGE;
     $project_edge_type = PhabricatorProjectObjectHasProjectEdgeType::EDGECONST;
     $object_phid = $object->getPHID();
     if ($object_phid) {
         $project_phids = PhabricatorEdgeQuery::loadDestinationPHIDs($object_phid, $project_edge_type);
         $project_phids = array_reverse($project_phids);
     } else {
         $project_phids = array();
     }
     $projects_field = id(new PhabricatorProjectsEditField())->setKey('projectPHIDs')->setLabel(pht('Projects'))->setEditTypeKey('projects')->setDescription(pht('Add or remove associated projects.'))->setAliases(array('project', 'projects'))->setIsCopyable(true)->setUseEdgeTransactions(true)->setEdgeTransactionDescriptions(pht('Add projects.'), pht('Remove projects.'), pht('Set associated projects, overwriting current value.'))->setCommentActionLabel(pht('Change Projects'))->setTransactionType($edge_type)->setMetadataValue('edge:type', $project_edge_type)->setValue($project_phids);
     return array($projects_field);
 }