diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php index 7651781343..197df72f46 100644 --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -118,6 +118,8 @@ phutil_register_library_map(array( 'ConduitAPI_conduit_getcertificate_Method' => 'applications/conduit/method/ConduitAPI_conduit_getcertificate_Method.php', 'ConduitAPI_conduit_ping_Method' => 'applications/conduit/method/ConduitAPI_conduit_ping_Method.php', 'ConduitAPI_conduit_query_Method' => 'applications/conduit/method/ConduitAPI_conduit_query_Method.php', + 'ConduitAPI_conpherence_Method' => 'applications/conpherence/conduit/ConduitAPI_conpherence_Method.php', + 'ConduitAPI_conpherence_createthread_Method' => 'applications/conpherence/conduit/ConduitAPI_conpherence_createthread_Method.php', 'ConduitAPI_daemon_launched_Method' => 'applications/daemon/conduit/ConduitAPI_daemon_launched_Method.php', 'ConduitAPI_daemon_log_Method' => 'applications/daemon/conduit/ConduitAPI_daemon_log_Method.php', 'ConduitAPI_daemon_setstatus_Method' => 'applications/daemon/conduit/ConduitAPI_daemon_setstatus_Method.php', @@ -1947,6 +1949,8 @@ phutil_register_library_map(array( 'ConduitAPI_conduit_getcertificate_Method' => 'ConduitAPIMethod', 'ConduitAPI_conduit_ping_Method' => 'ConduitAPIMethod', 'ConduitAPI_conduit_query_Method' => 'ConduitAPIMethod', + 'ConduitAPI_conpherence_Method' => 'ConduitAPIMethod', + 'ConduitAPI_conpherence_createthread_Method' => 'ConduitAPI_conpherence_Method', 'ConduitAPI_daemon_launched_Method' => 'ConduitAPIMethod', 'ConduitAPI_daemon_log_Method' => 'ConduitAPIMethod', 'ConduitAPI_daemon_setstatus_Method' => 'ConduitAPIMethod', diff --git a/src/applications/base/PhabricatorApplication.php b/src/applications/base/PhabricatorApplication.php index 6dbcb37662..ecffc18295 100644 --- a/src/applications/base/PhabricatorApplication.php +++ b/src/applications/base/PhabricatorApplication.php @@ -98,6 +98,10 @@ abstract class PhabricatorApplication { return null; } + public function getApplicationURI($path = '') { + return $this->getBaseURI().ltrim($path, '/'); + } + public function getIconURI() { return null; } diff --git a/src/applications/base/controller/PhabricatorController.php b/src/applications/base/controller/PhabricatorController.php index b2cdd3df61..70073813d1 100644 --- a/src/applications/base/controller/PhabricatorController.php +++ b/src/applications/base/controller/PhabricatorController.php @@ -141,7 +141,7 @@ abstract class PhabricatorController extends AphrontController { if (!$this->getCurrentApplication()) { throw new Exception("No application!"); } - return $this->getCurrentApplication()->getBaseURI().ltrim($path, '/'); + return $this->getCurrentApplication()->getApplicationURI($path); } public function buildApplicationPage($view, array $options) { diff --git a/src/applications/conpherence/conduit/ConduitAPI_conpherence_Method.php b/src/applications/conpherence/conduit/ConduitAPI_conpherence_Method.php new file mode 100644 index 0000000000..a3bcbee36d --- /dev/null +++ b/src/applications/conpherence/conduit/ConduitAPI_conpherence_Method.php @@ -0,0 +1,14 @@ + 'optional string', + 'message' => 'required string', + 'participantPHIDs' => 'required list' + ); + } + + public function defineReturnType() { + return 'nonempty dict'; + } + + public function defineErrorTypes() { + return array( + 'ERR_EMPTY_PARTICIPANT_PHIDS' => 'You must specify participant phids.', + 'ERR_EMPTY_MESSAGE' => 'You must specify a message.' + ); + } + + protected function execute(ConduitAPIRequest $request) { + + $participant_phids = $request->getValue('participantPHIDs', array()); + $message = $request->getValue('message'); + $title = $request->getValue('title'); + + list($errors, $conpherence) = ConpherenceEditor::createConpherence( + $request->getUser(), + $participant_phids, + $title, + $message, + PhabricatorContentSource::newFromConduitRequest($request)); + + if ($errors) { + foreach ($errors as $error_code) { + switch ($error_code) { + case ConpherenceEditor::ERROR_EMPTY_MESSAGE: + throw new ConduitException('ERR_EMPTY_MESSAGE'); + break; + case ConpherenceEditor::ERROR_EMPTY_PARTICIPANTS: + throw new ConduitException('ERR_EMPTY_PARTICIPANT_PHIDS'); + break; + } + } + } + + $id = $conpherence->getID(); + $uri = $this->getApplication()->getApplicationURI($id); + return array( + 'conpherenceID' => $id, + 'conpherencePHID' => $conpherence->getPHID(), + 'conpherenceURI' => $uri); + } +} diff --git a/src/applications/conpherence/controller/ConpherenceNewController.php b/src/applications/conpherence/controller/ConpherenceNewController.php index 7c9d553cba..25efe8c938 100644 --- a/src/applications/conpherence/controller/ConpherenceNewController.php +++ b/src/applications/conpherence/controller/ConpherenceNewController.php @@ -9,15 +9,9 @@ final class ConpherenceNewController extends ConpherenceController { $request = $this->getRequest(); $user = $request->getUser(); - $conpherence = id(new ConpherenceThread()) - ->attachParticipants(array()) - ->attachFilePHIDs(array()) - ->setMessageCount(0); $title = pht('New Message'); $participants = array(); $message = ''; - $files = array(); - $errors = array(); $e_participants = null; $e_message = null; @@ -29,72 +23,32 @@ final class ConpherenceNewController extends ConpherenceController { if ($request->isFormPost()) { $participants = $request->getArr('participants'); - if (empty($participants)) { - $e_participants = true; - $errors[] = pht('You must specify participants.'); - } else { - $participants[] = $user->getPHID(); - $participants = array_unique($participants); - $conpherence->setRecentParticipantPHIDs( - array_slice($participants, 0, 10)); - } - $message = $request->getStr('message'); - if (empty($message)) { - $e_message = true; - $errors[] = pht('You must write a message.'); - } + list($error_codes, $conpherence) = ConpherenceEditor::createConpherence( + $user, + $participants, + $conpherence_title = null, + $message, + PhabricatorContentSource::newFromRequest($request)); - $file_phids = - PhabricatorMarkupEngine::extractFilePHIDsFromEmbeddedFiles( - array($message)); - if ($file_phids) { - $files = id(new PhabricatorFileQuery()) - ->setViewer($user) - ->withPHIDs($file_phids) - ->execute(); - } - - if (!$errors) { - $conpherence->openTransaction(); - $conpherence->save(); - $xactions = array(); - $xactions[] = id(new ConpherenceTransaction()) - ->setTransactionType(ConpherenceTransactionType::TYPE_PARTICIPANTS) - ->setNewValue(array('+' => $participants)); - if ($files) { - $xactions[] = id(new ConpherenceTransaction()) - ->setTransactionType(ConpherenceTransactionType::TYPE_FILES) - ->setNewValue(array('+' => mpull($files, 'getPHID'))); + if ($error_codes) { + foreach ($error_codes as $error_code) { + switch ($error_code) { + case ConpherenceEditor::ERROR_EMPTY_MESSAGE: + $e_message = true; + break; + case ConpherenceEditor::ERROR_EMPTY_PARTICIPANTS: + $e_participants = true; + break; + } } - $xactions[] = id(new ConpherenceTransaction()) - ->setTransactionType(PhabricatorTransactions::TYPE_COMMENT) - ->attachComment( - id(new ConpherenceTransactionComment()) - ->setContent($message) - ->setConpherencePHID($conpherence->getPHID())); - - id(new ConpherenceEditor()) - ->setContentSourceFromRequest($request) - ->setContinueOnNoEffect(true) - ->setActor($user) - ->applyTransactions($conpherence, $xactions); - - $conpherence->saveTransaction(); - + } else { $uri = $this->getApplicationURI($conpherence->getID()); return id(new AphrontRedirectResponse()) ->setURI($uri); } } - $error_view = null; - if ($errors) { - $error_view = id(new AphrontErrorView()) - ->setTitle(pht('Conpherence Errors')) - ->setErrors($errors); - } - $participant_handles = array(); if ($participants) { $handles = id(new PhabricatorObjectHandleData($participants)) diff --git a/src/applications/conpherence/editor/ConpherenceEditor.php b/src/applications/conpherence/editor/ConpherenceEditor.php index 566905e489..d45c0e03ec 100644 --- a/src/applications/conpherence/editor/ConpherenceEditor.php +++ b/src/applications/conpherence/editor/ConpherenceEditor.php @@ -5,6 +5,81 @@ */ final class ConpherenceEditor extends PhabricatorApplicationTransactionEditor { + const ERROR_EMPTY_PARTICIPANTS = 'error-empty-participants'; + const ERROR_EMPTY_MESSAGE = 'error-empty-message'; + + public static function createConpherence( + PhabricatorUser $creator, + array $participant_phids, + $title, + $message, + PhabricatorContentSource $source) { + + $conpherence = id(new ConpherenceThread()) + ->attachParticipants(array()) + ->attachFilePHIDs(array()) + ->setMessageCount(0); + $files = array(); + $errors = array(); + if (empty($participant_phids)) { + $errors[] = self::ERROR_EMPTY_PARTICIPANTS; + } else { + $participant_phids[] = $creator->getPHID(); + $participant_phids = array_unique($participant_phids); + $conpherence->setRecentParticipantPHIDs( + array_slice($participant_phids, 0, 10)); + } + + if (empty($message)) { + $errors[] = self::ERROR_EMPTY_MESSAGE; + } + + $file_phids = + PhabricatorMarkupEngine::extractFilePHIDsFromEmbeddedFiles( + array($message)); + if ($file_phids) { + $files = id(new PhabricatorFileQuery()) + ->setViewer($creator) + ->withPHIDs($file_phids) + ->execute(); + } + + if (!$errors) { + $conpherence->openTransaction(); + $conpherence->save(); + $xactions = array(); + $xactions[] = id(new ConpherenceTransaction()) + ->setTransactionType(ConpherenceTransactionType::TYPE_PARTICIPANTS) + ->setNewValue(array('+' => $participant_phids)); + if ($files) { + $xactions[] = id(new ConpherenceTransaction()) + ->setTransactionType(ConpherenceTransactionType::TYPE_FILES) + ->setNewValue(array('+' => mpull($files, 'getPHID'))); + } + if ($title) { + $xactions[] = id(new ConpherenceTransaction()) + ->setTransactionType(ConpherenceTransactionType::TYPE_TITLE) + ->setNewValue($title); + } + $xactions[] = id(new ConpherenceTransaction()) + ->setTransactionType(PhabricatorTransactions::TYPE_COMMENT) + ->attachComment( + id(new ConpherenceTransactionComment()) + ->setContent($message) + ->setConpherencePHID($conpherence->getPHID())); + + id(new ConpherenceEditor()) + ->setContentSource($source) + ->setContinueOnNoEffect(true) + ->setActor($creator) + ->applyTransactions($conpherence, $xactions); + + $conpherence->saveTransaction(); + } + + return array($errors, $conpherence); + } + public function generateTransactionsFromText( ConpherenceThread $conpherence, $text) { diff --git a/src/applications/metamta/contentsource/PhabricatorContentSource.php b/src/applications/metamta/contentsource/PhabricatorContentSource.php index 414016fbcc..518f5b38f4 100644 --- a/src/applications/metamta/contentsource/PhabricatorContentSource.php +++ b/src/applications/metamta/contentsource/PhabricatorContentSource.php @@ -46,6 +46,12 @@ final class PhabricatorContentSource { )); } + public static function newFromConduitRequest(ConduitAPIRequest $request) { + return self::newForSource( + PhabricatorContentSource::SOURCE_CONDUIT, + array()); + } + public function serialize() { return json_encode(array( 'source' => $this->getSource(),