diff --git a/src/applications/herald/controller/HeraldWebhookTestController.php b/src/applications/herald/controller/HeraldWebhookTestController.php --- a/src/applications/herald/controller/HeraldWebhookTestController.php +++ b/src/applications/herald/controller/HeraldWebhookTestController.php @@ -52,6 +52,7 @@ $request = HeraldWebhookRequest::initializeNewWebhookRequest($hook) ->setObjectPHID($object->getPHID()) + ->setTriggerPHIDs(array($viewer->getPHID())) ->setIsTestAction(true) ->setTransactionPHIDs(mpull($xactions, 'getPHID')) ->save(); diff --git a/src/applications/herald/editor/HeraldWebhookEditor.php b/src/applications/herald/editor/HeraldWebhookEditor.php --- a/src/applications/herald/editor/HeraldWebhookEditor.php +++ b/src/applications/herald/editor/HeraldWebhookEditor.php @@ -19,4 +19,13 @@ return pht('%s created %s.', $author, $object); } + public function getTransactionTypes() { + $types = parent::getTransactionTypes(); + + $types[] = PhabricatorTransactions::TYPE_VIEW_POLICY; + $types[] = PhabricatorTransactions::TYPE_EDIT_POLICY; + + return $types; + } + } diff --git a/src/applications/herald/management/HeraldWebhookCallManagementWorkflow.php b/src/applications/herald/management/HeraldWebhookCallManagementWorkflow.php --- a/src/applications/herald/management/HeraldWebhookCallManagementWorkflow.php +++ b/src/applications/herald/management/HeraldWebhookCallManagementWorkflow.php @@ -78,11 +78,14 @@ ->setLimit(10) ->execute(); + $application_phid = id(new PhabricatorHeraldApplication())->getPHID(); + $request = HeraldWebhookRequest::initializeNewWebhookRequest($hook) ->setObjectPHID($object->getPHID()) ->setIsTestAction(true) ->setIsSilentAction((bool)$args->getArg('silent')) ->setIsSecureAction((bool)$args->getArg('secure')) + ->setTriggerPHIDs(array($application_phid)) ->setTransactionPHIDs(mpull($xactions, 'getPHID')) ->save(); diff --git a/src/applications/herald/phid/HeraldWebhookRequestPHIDType.php b/src/applications/herald/phid/HeraldWebhookRequestPHIDType.php --- a/src/applications/herald/phid/HeraldWebhookRequestPHIDType.php +++ b/src/applications/herald/phid/HeraldWebhookRequestPHIDType.php @@ -31,8 +31,7 @@ foreach ($handles as $phid => $handle) { $request = $objects[$phid]; - - // TODO: Fill this in. + $handle->setName(pht('Webhook Request %d', $request->getID())); } } diff --git a/src/applications/herald/storage/HeraldWebhookRequest.php b/src/applications/herald/storage/HeraldWebhookRequest.php --- a/src/applications/herald/storage/HeraldWebhookRequest.php +++ b/src/applications/herald/storage/HeraldWebhookRequest.php @@ -116,6 +116,14 @@ return $this->getProperty('transactionPHIDs', array()); } + public function setTriggerPHIDs(array $phids) { + return $this->setProperty('triggerPHIDs', $phids); + } + + public function getTriggerPHIDs() { + return $this->getProperty('triggerPHIDs', array()); + } + public function setIsSilentAction($bool) { return $this->setProperty('silent', $bool); } diff --git a/src/applications/herald/worker/HeraldWebhookWorker.php b/src/applications/herald/worker/HeraldWebhookWorker.php --- a/src/applications/herald/worker/HeraldWebhookWorker.php +++ b/src/applications/herald/worker/HeraldWebhookWorker.php @@ -138,11 +138,19 @@ ); } + $trigger_data = array(); + foreach ($request->getTriggerPHIDs() as $trigger_phid) { + $trigger_data[] = array( + 'phid' => $trigger_phid, + ); + } + $payload = array( - 'triggers' => array(), 'object' => array( + 'type' => phid_get_type($object->getPHID()), 'phid' => $object->getPHID(), ), + 'triggers' => $trigger_data, 'action' => array( 'test' => $request->getIsTestAction(), 'silent' => $request->getIsSilentAction(), diff --git a/src/applications/transactions/editor/PhabricatorApplicationTransactionEditor.php b/src/applications/transactions/editor/PhabricatorApplicationTransactionEditor.php --- a/src/applications/transactions/editor/PhabricatorApplicationTransactionEditor.php +++ b/src/applications/transactions/editor/PhabricatorApplicationTransactionEditor.php @@ -79,6 +79,7 @@ private $mailRemovedPHIDs = array(); private $mailUnexpandablePHIDs = array(); private $mailMutedPHIDs = array(); + private $webhookMap = array(); private $transactionQueue = array(); @@ -1307,6 +1308,8 @@ $mail->save(); } + $this->queueWebhooks($object, $xactions); + return $xactions; } @@ -3660,6 +3663,8 @@ 'mailStamps', 'mailUnexpandablePHIDs', 'mailMutedPHIDs', + 'webhookMap', + 'silent', ); } @@ -4240,4 +4245,56 @@ return $this; } + private function queueWebhooks($object, array $xactions) { + $hook_viewer = PhabricatorUser::getOmnipotentUser(); + + $webhook_map = $this->webhookMap; + if (!is_array($webhook_map)) { + $webhook_map = array(); + } + + // Add any "Firehose" hooks to the list of hooks we're going to call. + $firehose_hooks = id(new HeraldWebhookQuery()) + ->setViewer($hook_viewer) + ->withStatuses( + array( + HeraldWebhook::HOOKSTATUS_FIREHOSE, + )) + ->execute(); + foreach ($firehose_hooks as $firehose_hook) { + // This is "the hook itself is the reason this hook is being called", + // since we're including it because it's configured as a firehose + // hook. + $hook_phid = $firehose_hook->getPHID(); + $webhook_map[$hook_phid][] = $hook_phid; + } + + if (!$webhook_map) { + return; + } + + // NOTE: We're going to queue calls to disabled webhooks, they'll just + // immediately fail in the worker queue. This makes the behavior more + // visible. + + $call_hooks = id(new HeraldWebhookQuery()) + ->setViewer($hook_viewer) + ->withPHIDs(array_keys($webhook_map)) + ->execute(); + + foreach ($call_hooks as $call_hook) { + $trigger_phids = idx($webhook_map, $call_hook->getPHID()); + + $request = HeraldWebhookRequest::initializeNewWebhookRequest($call_hook) + ->setObjectPHID($object->getPHID()) + ->setTransactionPHIDs(mpull($xactions, 'getPHID')) + ->setTriggerPHIDs($trigger_phids) + ->setIsSilentAction((bool)$this->getIsSilent()) + ->setIsSecureAction((bool)$this->getMustEncrypt()) + ->save(); + + $request->queueCall(); + } + } + }