From 541e3d9e1cdf3a9d302897432f5f4b0a97e9e79b Mon Sep 17 00:00:00 2001 From: Bob Trahan Date: Thu, 25 Jun 2015 13:14:20 -0700 Subject: [PATCH 1/2] Conpherence - remove room vs message distinction as far as users are concerned Summary: Ref T8488, T8469, T8485. This is done in regards to T8488 as far as users are concerned. There's still some classes, and etc. that should be re-named probably. T8469 and T8485 are basically moot now though. Rather than having "Send Message" exposed, just expose "Create Room". Users get the full form. One change is "title" is now required. This diff removes the concept of "isRoom" entirely. Test Plan: Verifed a user with no conpherences had sensible data in both column view and full conpherence view. Created rooms with various policies and things worked well. Reviewers: epriestley Reviewed By: epriestley Subscribers: chad, epriestley, Korvin Maniphest Tasks: T8469, T8485, T8488 Differential Revision: https://secure.phabricator.com/D13351 --- resources/celerity/map.php | 30 ++-- .../20150619.conpherencerooms.1.sql | 6 + .../20150619.conpherencerooms.2.sql | 2 + .../20150619.conpherencerooms.3.sql | 2 + src/__phutil_library_map__.php | 4 - .../__tests__/ConpherenceRoomTestCase.php | 18 -- .../__tests__/ConpherenceThreadTestCase.php | 169 ------------------ .../PhabricatorConpherenceApplication.php | 7 +- ...erenceQueryTransactionConduitAPIMethod.php | 30 ++-- ...onpherenceUpdateThreadConduitAPIMethod.php | 16 +- .../controller/ConpherenceController.php | 14 +- .../controller/ConpherenceListController.php | 52 ++++-- .../controller/ConpherenceNewController.php | 90 ---------- .../ConpherenceNewRoomController.php | 44 ++++- ...ConpherenceNotificationPanelController.php | 2 +- .../ConpherenceRoomListController.php | 2 +- .../ConpherenceUpdateController.php | 67 +++---- .../conpherence/editor/ConpherenceEditor.php | 24 +-- .../ConpherenceHovercardEventListener.php | 4 +- .../ConpherenceCreateThreadMailReceiver.php | 2 +- .../PhabricatorConpherenceThreadPHIDType.php | 2 +- .../ConpherenceThreadMembersPolicyRule.php | 10 +- .../query/ConpherenceThreadQuery.php | 43 ----- .../query/ConpherenceThreadSearchEngine.php | 53 +----- .../conpherence/storage/ConpherenceThread.php | 88 +++------ .../storage/ConpherenceTransaction.php | 62 +------ .../view/ConpherenceDurableColumnView.php | 40 ++--- .../view/ConpherenceLayoutView.php | 4 +- .../view/ConpherenceThreadListView.php | 85 ++------- .../PhabricatorPeopleProfileController.php | 3 +- .../conpherence/behavior-widget-pane.js | 21 ++- 31 files changed, 261 insertions(+), 735 deletions(-) create mode 100644 resources/sql/autopatches/20150619.conpherencerooms.1.sql create mode 100644 resources/sql/autopatches/20150619.conpherencerooms.2.sql create mode 100644 resources/sql/autopatches/20150619.conpherencerooms.3.sql delete mode 100644 src/applications/conpherence/__tests__/ConpherenceThreadTestCase.php delete mode 100644 src/applications/conpherence/controller/ConpherenceNewController.php diff --git a/resources/celerity/map.php b/resources/celerity/map.php index ee119787c5..20e50ce92d 100644 --- a/resources/celerity/map.php +++ b/resources/celerity/map.php @@ -342,7 +342,7 @@ return array( 'rsrc/js/application/conpherence/behavior-menu.js' => 'd3782c93', 'rsrc/js/application/conpherence/behavior-pontificate.js' => '21ba5861', 'rsrc/js/application/conpherence/behavior-quicksand-blacklist.js' => '7927a7d3', - 'rsrc/js/application/conpherence/behavior-widget-pane.js' => '93568464', + 'rsrc/js/application/conpherence/behavior-widget-pane.js' => 'cafc59ab', 'rsrc/js/application/countdown/timer.js' => 'e4cc26b3', 'rsrc/js/application/daemon/behavior-bulk-job-reload.js' => 'edf8a145', 'rsrc/js/application/dashboard/behavior-dashboard-async-panel.js' => '469c0d9e', @@ -550,7 +550,7 @@ return array( 'javelin-behavior-conpherence-drag-and-drop-photo' => 'cf86d16a', 'javelin-behavior-conpherence-menu' => 'd3782c93', 'javelin-behavior-conpherence-pontificate' => '21ba5861', - 'javelin-behavior-conpherence-widget-pane' => '93568464', + 'javelin-behavior-conpherence-widget-pane' => 'cafc59ab', 'javelin-behavior-countdown-timer' => 'e4cc26b3', 'javelin-behavior-dark-console' => 'f411b6ae', 'javelin-behavior-dashboard-async-panel' => '469c0d9e', @@ -1501,19 +1501,6 @@ return array( 'javelin-dom', 'javelin-stratcom', ), - 93568464 => array( - 'javelin-behavior', - 'javelin-dom', - 'javelin-stratcom', - 'javelin-workflow', - 'javelin-util', - 'phabricator-notification', - 'javelin-behavior-device', - 'phuix-dropdown-menu', - 'phuix-action-list-view', - 'phuix-action-view', - 'conpherence-thread-manager', - ), '93d0c9e3' => array( 'javelin-behavior', 'javelin-stratcom', @@ -1768,6 +1755,19 @@ return array( 'javelin-stratcom', 'phabricator-phtize', ), + 'cafc59ab' => array( + 'javelin-behavior', + 'javelin-dom', + 'javelin-stratcom', + 'javelin-workflow', + 'javelin-util', + 'phabricator-notification', + 'javelin-behavior-device', + 'phuix-dropdown-menu', + 'phuix-action-list-view', + 'phuix-action-view', + 'conpherence-thread-manager', + ), 'ccf1cbf8' => array( 'javelin-install', 'javelin-dom', diff --git a/resources/sql/autopatches/20150619.conpherencerooms.1.sql b/resources/sql/autopatches/20150619.conpherencerooms.1.sql new file mode 100644 index 0000000000..c7c5c56053 --- /dev/null +++ b/resources/sql/autopatches/20150619.conpherencerooms.1.sql @@ -0,0 +1,6 @@ +UPDATE {$NAMESPACE}_conpherence.conpherence_thread + SET + viewPolicy = 'obj.conpherence.members', + editPolicy = 'obj.conpherence.members', + joinPolicy = 'obj.conpherence.members' + WHERE isRoom = 0; diff --git a/resources/sql/autopatches/20150619.conpherencerooms.2.sql b/resources/sql/autopatches/20150619.conpherencerooms.2.sql new file mode 100644 index 0000000000..e6c54a0921 --- /dev/null +++ b/resources/sql/autopatches/20150619.conpherencerooms.2.sql @@ -0,0 +1,2 @@ +ALTER TABLE {$NAMESPACE}_conpherence.conpherence_thread + DROP KEY `key_room`; diff --git a/resources/sql/autopatches/20150619.conpherencerooms.3.sql b/resources/sql/autopatches/20150619.conpherencerooms.3.sql new file mode 100644 index 0000000000..c4fb35b57c --- /dev/null +++ b/resources/sql/autopatches/20150619.conpherencerooms.3.sql @@ -0,0 +1,2 @@ +ALTER TABLE {$NAMESPACE}_conpherence.conpherence_thread + DROP COLUMN isRoom; diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php index 1a6a2cceed..8a05dd2512 100644 --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -238,7 +238,6 @@ phutil_register_library_map(array( 'ConpherenceLayoutView' => 'applications/conpherence/view/ConpherenceLayoutView.php', 'ConpherenceListController' => 'applications/conpherence/controller/ConpherenceListController.php', 'ConpherenceMenuItemView' => 'applications/conpherence/view/ConpherenceMenuItemView.php', - 'ConpherenceNewController' => 'applications/conpherence/controller/ConpherenceNewController.php', 'ConpherenceNewRoomController' => 'applications/conpherence/controller/ConpherenceNewRoomController.php', 'ConpherenceNotificationPanelController' => 'applications/conpherence/controller/ConpherenceNotificationPanelController.php', 'ConpherenceParticipant' => 'applications/conpherence/storage/ConpherenceParticipant.php', @@ -263,7 +262,6 @@ phutil_register_library_map(array( 'ConpherenceThreadQuery' => 'applications/conpherence/query/ConpherenceThreadQuery.php', 'ConpherenceThreadRemarkupRule' => 'applications/conpherence/remarkup/ConpherenceThreadRemarkupRule.php', 'ConpherenceThreadSearchEngine' => 'applications/conpherence/query/ConpherenceThreadSearchEngine.php', - 'ConpherenceThreadTestCase' => 'applications/conpherence/__tests__/ConpherenceThreadTestCase.php', 'ConpherenceTransaction' => 'applications/conpherence/storage/ConpherenceTransaction.php', 'ConpherenceTransactionComment' => 'applications/conpherence/storage/ConpherenceTransactionComment.php', 'ConpherenceTransactionQuery' => 'applications/conpherence/query/ConpherenceTransactionQuery.php', @@ -3609,7 +3607,6 @@ phutil_register_library_map(array( 'ConpherenceLayoutView' => 'AphrontView', 'ConpherenceListController' => 'ConpherenceController', 'ConpherenceMenuItemView' => 'AphrontTagView', - 'ConpherenceNewController' => 'ConpherenceController', 'ConpherenceNewRoomController' => 'ConpherenceController', 'ConpherenceNotificationPanelController' => 'ConpherenceController', 'ConpherenceParticipant' => 'ConpherenceDAO', @@ -3640,7 +3637,6 @@ phutil_register_library_map(array( 'ConpherenceThreadQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', 'ConpherenceThreadRemarkupRule' => 'PhabricatorObjectRemarkupRule', 'ConpherenceThreadSearchEngine' => 'PhabricatorApplicationSearchEngine', - 'ConpherenceThreadTestCase' => 'ConpherenceTestCase', 'ConpherenceTransaction' => 'PhabricatorApplicationTransaction', 'ConpherenceTransactionComment' => 'PhabricatorApplicationTransactionComment', 'ConpherenceTransactionQuery' => 'PhabricatorApplicationTransactionQuery', diff --git a/src/applications/conpherence/__tests__/ConpherenceRoomTestCase.php b/src/applications/conpherence/__tests__/ConpherenceRoomTestCase.php index 4c66a48348..03dd615481 100644 --- a/src/applications/conpherence/__tests__/ConpherenceRoomTestCase.php +++ b/src/applications/conpherence/__tests__/ConpherenceRoomTestCase.php @@ -69,20 +69,6 @@ final class ConpherenceRoomTestCase extends ConpherenceTestCase { $participant_phids, $conpherence->getRecentParticipantPHIDs()); - // test policy error as another user tries to add - $caught = null; - try { - $this->addParticipants( - $friend_2, - $conpherence, - array($friend_3->getPHID())); - } catch (PhabricatorPolicyException $ex) { - $caught = $ex; - } - $this->assertTrue($caught instanceof PhabricatorPolicyException); - - // update edit policy so user has a chance - $this->changeEditPolicy($creator, $conpherence, 'users'); // test add by other participant, so recent participation should // meaningfully change $participant_phids = array( @@ -129,7 +115,6 @@ final class ConpherenceRoomTestCase extends ConpherenceTestCase { public function testAddMessageWithFileAttachments() { $creator = $this->generateNewTestUser(); $friend_1 = $this->generateNewTestUser(); - $join_via_add = $this->generateNewTestUser(); $participant_map = array( $creator->getPHID() => $creator, @@ -144,9 +129,6 @@ final class ConpherenceRoomTestCase extends ConpherenceTestCase { $xactions = $this->addMessageWithFile($user, $conpherence); $this->assertEqual(2, count($xactions)); } - - $xactions = $this->addMessageWithFile($join_via_add, $conpherence); - $this->assertEqual(2, count($xactions)); } private function createRoom( diff --git a/src/applications/conpherence/__tests__/ConpherenceThreadTestCase.php b/src/applications/conpherence/__tests__/ConpherenceThreadTestCase.php deleted file mode 100644 index 3013e998fa..0000000000 --- a/src/applications/conpherence/__tests__/ConpherenceThreadTestCase.php +++ /dev/null @@ -1,169 +0,0 @@ - true, - ); - } - - public function testOneUserThreadCreate() { - $creator = $this->generateNewTestUser(); - $participant_phids = array($creator->getPHID()); - - $conpherence = $this->createThread($creator, $participant_phids); - - $this->assertTrue((bool)$conpherence->getID()); - $this->assertEqual(1, count($conpherence->getParticipants())); - $this->assertEqual( - $participant_phids, - $conpherence->getRecentParticipantPHIDs()); - } - - public function testNUserThreadCreate() { - $creator = $this->generateNewTestUser(); - $friend_1 = $this->generateNewTestUser(); - $friend_2 = $this->generateNewTestUser(); - $friend_3 = $this->generateNewTestUser(); - - $participant_phids = array( - $creator->getPHID(), - $friend_1->getPHID(), - $friend_2->getPHID(), - $friend_3->getPHID(), - ); - - $conpherence = $this->createThread($creator, $participant_phids); - - $this->assertTrue((bool)$conpherence->getID()); - $this->assertEqual(4, count($conpherence->getParticipants())); - $this->assertEqual( - $participant_phids, - $conpherence->getRecentParticipantPHIDs()); - } - - public function testThreadParticipantAddition() { - $creator = $this->generateNewTestUser(); - $friend_1 = $this->generateNewTestUser(); - $friend_2 = $this->generateNewTestUser(); - $friend_3 = $this->generateNewTestUser(); - - $participant_phids = array( - $creator->getPHID(), - $friend_1->getPHID(), - ); - - $conpherence = $this->createThread($creator, $participant_phids); - - $this->assertTrue((bool)$conpherence->getID()); - $this->assertEqual(2, count($conpherence->getParticipants())); - $this->assertEqual( - $participant_phids, - $conpherence->getRecentParticipantPHIDs()); - - // test add by creator - $participant_phids[] = $friend_2->getPHID(); - $this->addParticipants($creator, $conpherence, array($friend_2->getPHID())); - $this->assertEqual( - $participant_phids, - $conpherence->getRecentParticipantPHIDs()); - - // test add by other participant, so recent participation should - // meaningfully change - $participant_phids = array( - $friend_2->getPHID(), // actor - $creator->getPHID(), // last actor - $friend_1->getPHID(), - $friend_3->getPHID(), // new addition - ); - $this->addParticipants( - $friend_2, - $conpherence, - array($friend_3->getPHID())); - $this->assertEqual( - $participant_phids, - $conpherence->getRecentParticipantPHIDs()); - } - - public function testThreadParticipantDeletion() { - $creator = $this->generateNewTestUser(); - $friend_1 = $this->generateNewTestUser(); - $friend_2 = $this->generateNewTestUser(); - $friend_3 = $this->generateNewTestUser(); - - $participant_map = array( - $creator->getPHID() => $creator, - $friend_1->getPHID() => $friend_1, - $friend_2->getPHID() => $friend_2, - $friend_3->getPHID() => $friend_3, - ); - - $conpherence = $this->createThread( - $creator, - array_keys($participant_map)); - - foreach ($participant_map as $phid => $user) { - $this->removeParticipants($user, $conpherence, array($phid)); - unset($participant_map[$phid]); - $this->assertEqual( - count($participant_map), - count($conpherence->getParticipants())); - } - } - - public function testAddMessageWithFileAttachments() { - $creator = $this->generateNewTestUser(); - $friend_1 = $this->generateNewTestUser(); - $policy_exception_user = $this->generateNewTestUser(); - - $participant_map = array( - $creator->getPHID() => $creator, - $friend_1->getPHID() => $friend_1, - ); - - $conpherence = $this->createThread( - $creator, - array_keys($participant_map)); - - foreach ($participant_map as $phid => $user) { - $xactions = $this->addMessageWithFile($user, $conpherence); - $this->assertEqual(2, count($xactions), pht('hi')); - } - - $caught = null; - try { - $xactions = $this->addMessageWithFile( - $policy_exception_user, - $conpherence); - } catch (PhabricatorPolicyException $ex) { - $caught = $ex; - } - $this->assertTrue( - $caught instanceof PhabricatorPolicyException, - pht( - 'User not participating in thread should get policy exception '. - 'trying to add message.')); - $this->assertTrue( - $conpherence->establishConnection('w')->isReadLocking(), - pht( - 'Conpherence object should still be read locked from policy '. - 'exception.')); - $conpherence->endReadLocking(); - $conpherence->killTransaction(); - } - - private function createThread( - PhabricatorUser $creator, - array $participant_phids) { - - list($errors, $conpherence) = ConpherenceEditor::createThread( - $creator, - $participant_phids, - pht('Test'), - pht('Test'), - PhabricatorContentSource::newConsoleSource()); - return $conpherence; - } - -} diff --git a/src/applications/conpherence/application/PhabricatorConpherenceApplication.php b/src/applications/conpherence/application/PhabricatorConpherenceApplication.php index 5d36022a04..852daa8bee 100644 --- a/src/applications/conpherence/application/PhabricatorConpherenceApplication.php +++ b/src/applications/conpherence/application/PhabricatorConpherenceApplication.php @@ -11,7 +11,7 @@ final class PhabricatorConpherenceApplication extends PhabricatorApplication { } public function getShortDescription() { - return pht('Send Messages'); + return pht('Chat with Others'); } public function getFontIcon() { @@ -44,8 +44,7 @@ final class PhabricatorConpherenceApplication extends PhabricatorApplication { '(?P[1-9]\d*)/(?P[1-9]\d*)/' => 'ConpherenceViewController', 'columnview/' => 'ConpherenceColumnViewController', - 'new/' => 'ConpherenceNewController', - 'room/new/' => 'ConpherenceNewRoomController', + 'new/' => 'ConpherenceNewRoomController', 'search/(?:query/(?P[^/]+)/)?' => 'ConpherenceRoomListController', 'panel/' => 'ConpherenceNotificationPanelController', @@ -59,7 +58,7 @@ final class PhabricatorConpherenceApplication extends PhabricatorApplication { $items = array(); $item = id(new PHUIListItemView()) - ->setName(pht('Conpherence Thread')) + ->setName(pht('Conpherence Room')) ->setIcon('fa-comments') ->setWorkflow(true) ->setHref($this->getBaseURI().'new/'); diff --git a/src/applications/conpherence/conduit/ConpherenceQueryTransactionConduitAPIMethod.php b/src/applications/conpherence/conduit/ConpherenceQueryTransactionConduitAPIMethod.php index e014dc742a..7de3b0678d 100644 --- a/src/applications/conpherence/conduit/ConpherenceQueryTransactionConduitAPIMethod.php +++ b/src/applications/conpherence/conduit/ConpherenceQueryTransactionConduitAPIMethod.php @@ -10,15 +10,15 @@ final class ConpherenceQueryTransactionConduitAPIMethod public function getMethodDescription() { return pht( 'Query for transactions for the logged in user within a specific '. - 'Conpherence thread. You can specify the thread by ID or PHID. '. + 'Conpherence room. You can specify the room by ID or PHID. '. 'Otherwise, specify limit and offset to query the most recent '. - 'transactions within the Conpherence for the logged in user.'); + 'transactions within the Conpherence room for the logged in user.'); } protected function defineParamTypes() { return array( - 'threadID' => 'optional int', - 'threadPHID' => 'optional phid', + 'roomID' => 'optional int', + 'roomPHID' => 'optional phid', 'limit' => 'optional int', 'offset' => 'optional int', ); @@ -30,28 +30,28 @@ final class ConpherenceQueryTransactionConduitAPIMethod protected function defineErrorTypes() { return array( - 'ERR_USAGE_NO_THREAD_ID' => pht( - 'You must specify a thread id or thread PHID to query transactions '. + 'ERR_USAGE_NO_ROOM_ID' => pht( + 'You must specify a room id or room PHID to query transactions '. 'from.'), ); } protected function execute(ConduitAPIRequest $request) { $user = $request->getUser(); - $thread_id = $request->getValue('threadID'); - $thread_phid = $request->getValue('threadPHID'); + $room_id = $request->getValue('roomID'); + $room_phid = $request->getValue('roomPHID'); $limit = $request->getValue('limit'); $offset = $request->getValue('offset'); $query = id(new ConpherenceThreadQuery()) ->setViewer($user); - if ($thread_id) { - $query->withIDs(array($thread_id)); - } else if ($thread_phid) { - $query->withPHIDs(array($thread_phid)); + if ($room_id) { + $query->withIDs(array($room_id)); + } else if ($room_phid) { + $query->withPHIDs(array($room_phid)); } else { - throw new ConduitException('ERR_USAGE_NO_THREAD_ID'); + throw new ConduitException('ERR_USAGE_NO_ROOM_ID'); } $conpherence = $query->executeOne(); @@ -87,8 +87,8 @@ final class ConpherenceQueryTransactionConduitAPIMethod 'transactionMetadata' => $transaction->getMetadata(), 'authorPHID' => $transaction->getAuthorPHID(), 'dateCreated' => $transaction->getDateCreated(), - 'conpherenceID' => $conpherence->getID(), - 'conpherencePHID' => $conpherence->getPHID(), + 'roomID' => $conpherence->getID(), + 'roomPHID' => $conpherence->getPHID(), ); } return $data; diff --git a/src/applications/conpherence/conduit/ConpherenceUpdateThreadConduitAPIMethod.php b/src/applications/conpherence/conduit/ConpherenceUpdateThreadConduitAPIMethod.php index 66bbdab7e3..c7ea1405cd 100644 --- a/src/applications/conpherence/conduit/ConpherenceUpdateThreadConduitAPIMethod.php +++ b/src/applications/conpherence/conduit/ConpherenceUpdateThreadConduitAPIMethod.php @@ -8,7 +8,7 @@ final class ConpherenceUpdateThreadConduitAPIMethod } public function getMethodDescription() { - return pht('Update an existing conpherence thread.'); + return pht('Update an existing conpherence room.'); } protected function defineParamTypes() { @@ -28,13 +28,13 @@ final class ConpherenceUpdateThreadConduitAPIMethod protected function defineErrorTypes() { return array( - 'ERR_USAGE_NO_THREAD_ID' => pht( - 'You must specify a thread id or thread phid to query transactions '. + 'ERR_USAGE_NO_ROOM_ID' => pht( + 'You must specify a room id or room phid to query transactions '. 'from.'), - 'ERR_USAGE_THREAD_NOT_FOUND' => pht( - 'Thread does not exist or logged in user can not see it.'), + 'ERR_USAGE_ROOM_NOT_FOUND' => pht( + 'room does not exist or logged in user can not see it.'), 'ERR_USAGE_ONLY_SELF_REMOVE' => pht( - 'Only a user can remove themselves from a thread.'), + 'Only a user can remove themselves from a room.'), 'ERR_USAGE_NO_UPDATES' => pht( 'You must specify data that actually updates the conpherence.'), ); @@ -52,11 +52,11 @@ final class ConpherenceUpdateThreadConduitAPIMethod } else if ($phid) { $query->withPHIDs(array($phid)); } else { - throw new ConduitException('ERR_USAGE_NO_THREAD_ID'); + throw new ConduitException('ERR_USAGE_NO_ROOM_ID'); } $conpherence = $query->executeOne(); if (!$conpherence) { - throw new ConduitException('ERR_USAGE_THREAD_NOT_FOUND'); + throw new ConduitException('ERR_USAGE_ROOM_NOT_FOUND'); } $source = PhabricatorContentSource::newFromConduitRequest($request); diff --git a/src/applications/conpherence/controller/ConpherenceController.php b/src/applications/conpherence/controller/ConpherenceController.php index e78b5597dc..ee7f13fa21 100644 --- a/src/applications/conpherence/controller/ConpherenceController.php +++ b/src/applications/conpherence/controller/ConpherenceController.php @@ -16,7 +16,7 @@ abstract class ConpherenceController extends PhabricatorController { $nav = new PHUIListView(); $nav->newLink( - pht('New Message'), + pht('New Room'), $this->getApplicationURI('new/')); $nav->addMenuItem( @@ -51,20 +51,20 @@ abstract class ConpherenceController extends PhabricatorController { ->addAction( id(new PHUIListItemView()) ->setName(pht('New Room')) - ->setHref($this->getApplicationURI('room/new/')) + ->setHref($this->getApplicationURI('new/')) ->setIcon('fa-plus-square') ->setWorkflow(true)); } else { $crumbs ->addAction( id(new PHUIListItemView()) - ->setName(pht('New Message')) + ->setName(pht('New Room')) ->setHref($this->getApplicationURI('new/')) ->setIcon('fa-plus-square') ->setWorkflow(true)) ->addAction( id(new PHUIListItemView()) - ->setName(pht('Thread')) + ->setName(pht('Room')) ->setHref('#') ->setIcon('fa-bars') ->setStyle('display: none;') @@ -81,14 +81,8 @@ abstract class ConpherenceController extends PhabricatorController { $crumbs = $this->buildApplicationCrumbs(); $data = $conpherence->getDisplayData($this->getViewer()); - if ($conpherence->getID() && $conpherence->getIsRoom()) { - $icon = $conpherence->getPolicyIconName($policy_objects); - } else { - $icon = null; - } $crumbs->addCrumb( id(new PHUICrumbView()) - ->setIcon($icon) ->setName($data['title']) ->setHref($this->getApplicationURI('update/'.$conpherence->getID().'/')) ->setWorkflow(true)); diff --git a/src/applications/conpherence/controller/ConpherenceListController.php b/src/applications/conpherence/controller/ConpherenceListController.php index ad672ff6d8..dbabc9b7d9 100644 --- a/src/applications/conpherence/controller/ConpherenceListController.php +++ b/src/applications/conpherence/controller/ConpherenceListController.php @@ -34,7 +34,7 @@ final class ConpherenceListController extends ConpherenceController { $title = pht('Conpherence'); $conpherence = null; - $limit = ConpherenceThreadListView::SEE_MORE_LIMIT * 5; + $limit = (ConpherenceThreadListView::SEE_MORE_LIMIT * 2) + 1; $all_participation = array(); $mode = $this->determineMode(); @@ -62,9 +62,28 @@ final class ConpherenceListController extends ConpherenceController { } else { $menu_participation = $cursor; } - $all_participation = - array($conpherence->getPHID() => $menu_participation) + - $all_participation; + + // check to see if the loaded conpherence is going to show up + // within the SEE_MORE_LIMIT amount of conpherences. + // If its not there, then we just pre-pend it as the "first" + // conpherence so folks have a navigation item in the menu. + $count = 0; + $found = false; + foreach ($all_participation as $phid => $curr_participation) { + if ($conpherence->getPHID() == $phid) { + $found = true; + break; + } + $count++; + if ($count > ConpherenceThreadListView::SEE_MORE_LIMIT) { + break; + } + } + if (!$found) { + $all_participation = + array($conpherence->getPHID() => $menu_participation) + + $all_participation; + } break; case self::UNSELECTED_MODE: default: @@ -93,22 +112,21 @@ final class ConpherenceListController extends ConpherenceController { ->setThreadView($thread_view) ->setRole('list'); if ($conpherence) { - $policy_objects = id(new PhabricatorPolicyQuery()) - ->setViewer($user) - ->setObject($conpherence) - ->execute(); - $layout->setHeader($this->buildHeaderPaneContent( - $conpherence, - $policy_objects)); $layout->setThread($conpherence); } else { - $thread = ConpherenceThread::initializeNewThread($user); - $thread->attachHandles(array()); - $thread->attachTransactions(array()); - $thread->makeEphemeral(); - $layout->setHeader( - $this->buildHeaderPaneContent($thread, array())); + // make a dummy conpherence so we can render something + $conpherence = ConpherenceThread::initializeNewRoom($user); + $conpherence->attachHandles(array()); + $conpherence->attachTransactions(array()); + $conpherence->makeEphemeral(); } + $policy_objects = id(new PhabricatorPolicyQuery()) + ->setViewer($user) + ->setObject($conpherence) + ->execute(); + $layout->setHeader($this->buildHeaderPaneContent( + $conpherence, + $policy_objects)); $response = $this->buildApplicationPage( $layout, array( diff --git a/src/applications/conpherence/controller/ConpherenceNewController.php b/src/applications/conpherence/controller/ConpherenceNewController.php deleted file mode 100644 index 102cf0e5ea..0000000000 --- a/src/applications/conpherence/controller/ConpherenceNewController.php +++ /dev/null @@ -1,90 +0,0 @@ -getUser(); - - $title = pht('New Message'); - $participants = array(); - $participant_prefill = null; - $message = ''; - $e_participants = null; - $e_message = null; - $errors = array(); - - // this comes from ajax requests from all over. should be a single phid. - - if ($request->isFormPost()) { - $participants = $request->getArr('participants'); - $message = $request->getStr('message'); - list($error_codes, $conpherence) = ConpherenceEditor::createThread( - $user, - $participants, - $conpherence_title = null, - $message, - PhabricatorContentSource::newFromRequest($request)); - - if ($error_codes) { - foreach ($error_codes as $error_code) { - switch ($error_code) { - case ConpherenceEditor::ERROR_EMPTY_MESSAGE: - $e_message = pht('Required'); - $errors[] = pht( - 'You can not send an empty message.'); - break; - case ConpherenceEditor::ERROR_EMPTY_PARTICIPANTS: - $e_participants = pht('Required'); - $errors[] = pht( - 'You must choose at least one recipient for your '. - 'message.'); - break; - } - } - } else { - return id(new AphrontRedirectResponse()) - ->setURI('/'.$conpherence->getMonogram()); - } - } else { - $participant_prefill = $request->getStr('participant'); - if ($participant_prefill) { - $participants[] = $participant_prefill; - } - } - - $submit_uri = $this->getApplicationURI('new/'); - $cancel_uri = $this->getApplicationURI(); - - $dialog = id(new AphrontDialogView()) - ->setWidth(AphrontDialogView::WIDTH_FORM) - ->setErrors($errors) - ->setUser($user) - ->setTitle($title) - ->addCancelButton($cancel_uri) - ->addSubmitButton(pht('Send Message')); - - $form = id(new AphrontFormView()) - ->setUser($user) - ->setFullWidth(true) - ->appendControl( - id(new AphrontFormTokenizerControl()) - ->setName('participants') - ->setValue($participants) - ->setUser($user) - ->setDatasource(new PhabricatorPeopleDatasource()) - ->setLabel(pht('To')) - ->setError($e_participants)) - ->appendChild( - id(new PhabricatorRemarkupControl()) - ->setUser($user) - ->setName('message') - ->setValue($message) - ->setLabel(pht('Message')) - ->setError($e_message)); - - $dialog->appendForm($form); - - return id(new AphrontDialogResponse())->setDialog($dialog); - } - -} diff --git a/src/applications/conpherence/controller/ConpherenceNewRoomController.php b/src/applications/conpherence/controller/ConpherenceNewRoomController.php index 28c51ea7d6..5578741e89 100644 --- a/src/applications/conpherence/controller/ConpherenceNewRoomController.php +++ b/src/applications/conpherence/controller/ConpherenceNewRoomController.php @@ -10,12 +10,18 @@ final class ConpherenceNewRoomController extends ConpherenceController { $validation_exception = null; $conpherence = ConpherenceThread::initializeNewRoom($user); + $participants = array(); if ($request->isFormPost()) { - + $editor = new ConpherenceEditor(); $xactions = array(); + + $participants = $request->getArr('participants'); + $participants[] = $user->getPHID(); + $participants = array_unique($participants); $xactions[] = id(new ConpherenceTransaction()) ->setTransactionType(ConpherenceTransaction::TYPE_PARTICIPANTS) - ->setNewValue(array('+' => array($user->getPHID()))); + ->setNewValue(array('+' => $participants)); + $xactions[] = id(new ConpherenceTransaction()) ->setTransactionType(ConpherenceTransaction::TYPE_TITLE) ->setNewValue($request->getStr('title')); @@ -29,8 +35,17 @@ final class ConpherenceNewRoomController extends ConpherenceController { ->setTransactionType(PhabricatorTransactions::TYPE_JOIN_POLICY) ->setNewValue($request->getStr('joinPolicy')); + $message = $request->getStr('message'); + if ($message) { + $message_xactions = $editor->generateTransactionsFromText( + $user, + $conpherence, + $message); + $xactions = array_merge($xactions, $message_xactions); + } + try { - id(new ConpherenceEditor()) + $editor ->setContentSourceFromRequest($request) ->setContinueOnNoEffect(true) ->setActor($user) @@ -47,6 +62,10 @@ final class ConpherenceNewRoomController extends ConpherenceController { $conpherence->setEditPolicy($request->getStr('editPolicy')); $conpherence->setJoinPolicy($request->getStr('joinPolicy')); } + } else { + if ($request->getStr('participant')) { + $participants[] = $request->getStr('participant'); + } } $policies = id(new PhabricatorPolicyQuery()) @@ -54,7 +73,7 @@ final class ConpherenceNewRoomController extends ConpherenceController { ->setObject($conpherence) ->execute(); - $submit_uri = $this->getApplicationURI('room/new/'); + $submit_uri = $this->getApplicationURI('new/'); $cancel_uri = $this->getApplicationURI('search/'); $dialog = $this->newDialog() @@ -67,13 +86,19 @@ final class ConpherenceNewRoomController extends ConpherenceController { $form = id(new PHUIFormLayoutView()) ->setUser($user) - ->setFullWidth(true) ->appendChild( id(new AphrontFormTextControl()) ->setError($e_title) - ->setLabel(pht('Title')) + ->setLabel(pht('Name')) ->setName('title') ->setValue($request->getStr('title'))) + ->appendChild( + id(new AphrontFormTokenizerControl()) + ->setName('participants') + ->setUser($user) + ->setDatasource(new PhabricatorPeopleDatasource()) + ->setValue($participants) + ->setLabel(pht('Other Participants'))) ->appendChild( id(new AphrontFormPolicyControl()) ->setName('viewPolicy') @@ -91,7 +116,12 @@ final class ConpherenceNewRoomController extends ConpherenceController { ->setName('joinPolicy') ->setPolicyObject($conpherence) ->setCapability(PhabricatorPolicyCapability::CAN_JOIN) - ->setPolicies($policies)); + ->setPolicies($policies)) + ->appendChild( + id(new PhabricatorRemarkupControl()) + ->setUser($user) + ->setName('message') + ->setLabel(pht('First Message'))); $dialog->appendChild($form); diff --git a/src/applications/conpherence/controller/ConpherenceNotificationPanelController.php b/src/applications/conpherence/controller/ConpherenceNotificationPanelController.php index ab5b7470fc..63e777818c 100644 --- a/src/applications/conpherence/controller/ConpherenceNotificationPanelController.php +++ b/src/applications/conpherence/controller/ConpherenceNotificationPanelController.php @@ -83,7 +83,7 @@ final class ConpherenceNotificationPanelController array( 'href' => '/conpherence/', ), - pht('Messages')), + pht('Rooms')), $content); $unread = id(new ConpherenceParticipantCountQuery()) diff --git a/src/applications/conpherence/controller/ConpherenceRoomListController.php b/src/applications/conpherence/controller/ConpherenceRoomListController.php index 43c36d20d1..704f210781 100644 --- a/src/applications/conpherence/controller/ConpherenceRoomListController.php +++ b/src/applications/conpherence/controller/ConpherenceRoomListController.php @@ -33,7 +33,7 @@ final class ConpherenceRoomListController extends ConpherenceController { $nav->setBaseURI(new PhutilURI($this->getApplicationURI())); if ($for_app) { - $nav->addFilter('room/new/', pht('Create Room')); + $nav->addFilter('new/', pht('Create Room')); } id(new ConpherenceThreadSearchEngine()) diff --git a/src/applications/conpherence/controller/ConpherenceUpdateController.php b/src/applications/conpherence/controller/ConpherenceUpdateController.php index c88aee23d7..0739c4054c 100644 --- a/src/applications/conpherence/controller/ConpherenceUpdateController.php +++ b/src/applications/conpherence/controller/ConpherenceUpdateController.php @@ -188,17 +188,15 @@ final class ConpherenceUpdateController $xactions[] = id(new ConpherenceTransaction()) ->setTransactionType(ConpherenceTransaction::TYPE_TITLE) ->setNewValue($title); - if ($conpherence->getIsRoom()) { - $xactions[] = id(new ConpherenceTransaction()) - ->setTransactionType(PhabricatorTransactions::TYPE_VIEW_POLICY) - ->setNewValue($request->getStr('viewPolicy')); - $xactions[] = id(new ConpherenceTransaction()) - ->setTransactionType(PhabricatorTransactions::TYPE_EDIT_POLICY) - ->setNewValue($request->getStr('editPolicy')); - $xactions[] = id(new ConpherenceTransaction()) - ->setTransactionType(PhabricatorTransactions::TYPE_JOIN_POLICY) - ->setNewValue($request->getStr('joinPolicy')); - } + $xactions[] = id(new ConpherenceTransaction()) + ->setTransactionType(PhabricatorTransactions::TYPE_VIEW_POLICY) + ->setNewValue($request->getStr('viewPolicy')); + $xactions[] = id(new ConpherenceTransaction()) + ->setTransactionType(PhabricatorTransactions::TYPE_EDIT_POLICY) + ->setNewValue($request->getStr('editPolicy')); + $xactions[] = id(new ConpherenceTransaction()) + ->setTransactionType(PhabricatorTransactions::TYPE_JOIN_POLICY) + ->setNewValue($request->getStr('joinPolicy')); if (!$request->getExists('force_ajax')) { $response_mode = 'redirect'; } @@ -245,8 +243,11 @@ final class ConpherenceUpdateController ->setContent($content); break; case 'go-home': - return id(new AphrontRedirectResponse()) - ->setURI($this->getApplicationURI()); + $content = array( + 'href' => $this->getApplicationURI(), + ); + return id(new AphrontAjaxResponse()) + ->setContent($content); break; case 'redirect': default: @@ -323,18 +324,21 @@ final class ConpherenceUpdateController $user = $request->getUser(); $remove_person = $request->getStr('remove_person'); $participants = $conpherence->getParticipants(); - if ($conpherence->getIsRoom()) { - $message = pht( - 'Are you sure you want to remove yourself from this room?'); - } else { - $message = pht( - 'Are you sure you want to remove yourself from this thread?'); + + $message = pht( + 'Are you sure you want to leave this room?'); + $test_conpherence = clone $conpherence; + $test_conpherence->attachParticipants(array()); + if (!PhabricatorPolicyFilter::hasCapability( + $user, + $test_conpherence, + PhabricatorPolicyCapability::CAN_VIEW)) { if (count($participants) == 1) { $message .= pht( - 'The thread will be inaccessible forever and ever.'); + ' The room will be inaccessible forever and ever.'); } else { $message .= pht( - 'Someone else in the thread can add you back later.'); + ' Someone else in the room can add you back later.'); } } $body = phutil_tag( @@ -345,7 +349,7 @@ final class ConpherenceUpdateController require_celerity_resource('conpherence-update-css'); return id(new AphrontDialogView()) - ->setTitle(pht('Remove Participants')) + ->setTitle(pht('Leave Room')) ->addHiddenInput('action', 'remove_person') ->addHiddenInput('remove_person', $remove_person) ->addHiddenInput( @@ -362,6 +366,7 @@ final class ConpherenceUpdateController $request = $this->getRequest(); $user = $request->getUser(); + $title = pht('Update Room'); $form = id(new PHUIFormLayoutView()) ->appendChild($error_view) ->appendChild( @@ -399,14 +404,13 @@ final class ConpherenceUpdateController ->setLabel(pht('Image'))); } - if ($conpherence->getIsRoom()) { - $title = pht('Update Room'); - $policies = id(new PhabricatorPolicyQuery()) - ->setViewer($user) - ->setObject($conpherence) - ->execute(); + $policies = id(new PhabricatorPolicyQuery()) + ->setViewer($user) + ->setObject($conpherence) + ->execute(); - $form->appendChild( + $form + ->appendChild( id(new AphrontFormPolicyControl()) ->setName('viewPolicy') ->setPolicyObject($conpherence) @@ -424,9 +428,6 @@ final class ConpherenceUpdateController ->setPolicyObject($conpherence) ->setCapability(PhabricatorPolicyCapability::CAN_JOIN) ->setPolicies($policies)); - } else { - $title = pht('Update Thread'); - } require_celerity_resource('conpherence-update-css'); $view = id(new AphrontDialogView()) @@ -520,7 +521,7 @@ final class ConpherenceUpdateController $nav_item = id(new ConpherenceThreadListView()) ->setUser($user) ->setBaseURI($this->getApplicationURI()) - ->renderSingleThread($conpherence); + ->renderSingleThread($conpherence, $policy_objects); $nav_item = hsprintf('%s', $nav_item); break; case ConpherenceUpdateActions::MESSAGE: diff --git a/src/applications/conpherence/editor/ConpherenceEditor.php b/src/applications/conpherence/editor/ConpherenceEditor.php index c9445216fe..299b799d3e 100644 --- a/src/applications/conpherence/editor/ConpherenceEditor.php +++ b/src/applications/conpherence/editor/ConpherenceEditor.php @@ -10,7 +10,7 @@ final class ConpherenceEditor extends PhabricatorApplicationTransactionEditor { } public function getEditorObjectsDescription() { - return pht('Conpherence Threads'); + return pht('Conpherence Rooms'); } public static function createThread( @@ -20,7 +20,7 @@ final class ConpherenceEditor extends PhabricatorApplicationTransactionEditor { $message, PhabricatorContentSource $source) { - $conpherence = ConpherenceThread::initializeNewThread($creator); + $conpherence = ConpherenceThread::initializeNewRoom($creator); $files = array(); $errors = array(); if (empty($participant_phids)) { @@ -456,7 +456,7 @@ final class ConpherenceEditor extends PhabricatorApplicationTransactionEditor { $is_leave = (($rem === array($actor_phid)) && !$add); if ($is_join) { - // You need CAN_JOIN to join a thread / room. + // You need CAN_JOIN to join a room. PhabricatorPolicyFilter::requireCapability( $this->requireActor(), $object, @@ -583,11 +583,7 @@ final class ConpherenceEditor extends PhabricatorApplicationTransactionEditor { $href = PhabricatorEnv::getProductionURI( '/'.$object->getMonogram().'?settings'); - if ($object->getIsRoom()) { - $label = pht('EMAIL PREFERENCES FOR THIS ROOM'); - } else { - $label = pht('EMAIL PREFERENCES FOR THIS MESSAGE'); - } + $label = pht('EMAIL PREFERENCES FOR THIS ROOM'); $body->addLinkSection($label, $href); } @@ -644,19 +640,15 @@ final class ConpherenceEditor extends PhabricatorApplicationTransactionEditor { switch ($type) { case ConpherenceTransaction::TYPE_TITLE: - if (!$object->getIsRoom()) { - continue; + if (empty($xactions)) { + break; } $missing = $this->validateIsEmptyTextField( $object->getTitle(), $xactions); if ($missing) { - if ($object->getIsRoom()) { - $detail = pht('Room title is required.'); - } else { - $detail = pht('Thread title can not be blank.'); - } + $detail = pht('Room title is required.'); $error = new PhabricatorApplicationTransactionValidationError( $type, pht('Required'), @@ -704,7 +696,7 @@ final class ConpherenceEditor extends PhabricatorApplicationTransactionEditor { $errors[] = new PhabricatorApplicationTransactionValidationError( $type, pht('Invalid'), - pht('New thread member "%s" is not a valid user.', $phid), + pht('New room participant "%s" is not a valid user.', $phid), $xaction); } } diff --git a/src/applications/conpherence/events/ConpherenceHovercardEventListener.php b/src/applications/conpherence/events/ConpherenceHovercardEventListener.php index 616af030ea..dcf4f08294 100644 --- a/src/applications/conpherence/events/ConpherenceHovercardEventListener.php +++ b/src/applications/conpherence/events/ConpherenceHovercardEventListener.php @@ -30,8 +30,8 @@ final class ConpherenceHovercardEventListener extends PhabricatorEventListener { return; } - $conpherence_uri = new PhutilURI( - '/conpherence/new/?participant='.$user->getPHID()); + $conpherence_uri = id(new PhutilURI('/conpherence/new/')) + ->setQueryParam('participant', $user->getPHID()); $name = pht('Send a Message'); $hovercard->addAction($name, $conpherence_uri, true); diff --git a/src/applications/conpherence/mail/ConpherenceCreateThreadMailReceiver.php b/src/applications/conpherence/mail/ConpherenceCreateThreadMailReceiver.php index c7dc69ea87..aacf4426d4 100644 --- a/src/applications/conpherence/mail/ConpherenceCreateThreadMailReceiver.php +++ b/src/applications/conpherence/mail/ConpherenceCreateThreadMailReceiver.php @@ -53,7 +53,7 @@ final class ConpherenceCreateThreadMailReceiver $phids = mpull($users, 'getPHID'); $conpherence = id(new ConpherenceReplyHandler()) - ->setMailReceiver(ConpherenceThread::initializeNewThread($sender)) + ->setMailReceiver(ConpherenceThread::initializeNewRoom($sender)) ->setMailAddedParticipantPHIDs($phids) ->setActor($sender) ->setExcludeMailRecipientPHIDs($mail->loadExcludeMailRecipientPHIDs()) diff --git a/src/applications/conpherence/phid/PhabricatorConpherenceThreadPHIDType.php b/src/applications/conpherence/phid/PhabricatorConpherenceThreadPHIDType.php index 81a5a49043..98f0d74797 100644 --- a/src/applications/conpherence/phid/PhabricatorConpherenceThreadPHIDType.php +++ b/src/applications/conpherence/phid/PhabricatorConpherenceThreadPHIDType.php @@ -5,7 +5,7 @@ final class PhabricatorConpherenceThreadPHIDType extends PhabricatorPHIDType { const TYPECONST = 'CONP'; public function getTypeName() { - return pht('Conpherence Thread'); + return pht('Conpherence Room'); } public function newObject() { diff --git a/src/applications/conpherence/policyrule/ConpherenceThreadMembersPolicyRule.php b/src/applications/conpherence/policyrule/ConpherenceThreadMembersPolicyRule.php index 658ee42bdb..9cf2c2861f 100644 --- a/src/applications/conpherence/policyrule/ConpherenceThreadMembersPolicyRule.php +++ b/src/applications/conpherence/policyrule/ConpherenceThreadMembersPolicyRule.php @@ -8,15 +8,19 @@ final class ConpherenceThreadMembersPolicyRule } public function getObjectPolicyName() { - return pht('Thread Members'); + return pht('Room Participants'); } public function getPolicyExplanation() { - return pht('Members of this thread can take this action.'); + return pht('Participants in this room can take this action.'); } public function getRuleDescription() { - return pht('thread members'); + return pht('room participants'); + } + + public function getObjectPolicyIcon() { + return 'fa-comments'; } public function canApplyToObject(PhabricatorPolicyInterface $object) { diff --git a/src/applications/conpherence/query/ConpherenceThreadQuery.php b/src/applications/conpherence/query/ConpherenceThreadQuery.php index a04037cf6c..7006ee759d 100644 --- a/src/applications/conpherence/query/ConpherenceThreadQuery.php +++ b/src/applications/conpherence/query/ConpherenceThreadQuery.php @@ -8,7 +8,6 @@ final class ConpherenceThreadQuery private $phids; private $ids; private $participantPHIDs; - private $isRoom; private $needParticipants; private $needWidgetData; private $needCropPics; @@ -71,11 +70,6 @@ final class ConpherenceThreadQuery return $this; } - public function withIsRoom($bool) { - $this->isRoom = $bool; - return $this; - } - public function setAfterTransactionID($id) { $this->afterTransactionID = $id; return $this; @@ -166,16 +160,6 @@ final class ConpherenceThreadQuery id(new ConpherenceParticipant())->getTableName()); } - $viewer = $this->getViewer(); - if ($this->shouldJoinForViewer($viewer)) { - $joins[] = qsprintf( - $conn_r, - 'LEFT JOIN %T v ON v.conpherencePHID = conpherence_thread.phid '. - 'AND v.participantPHID = %s', - id(new ConpherenceParticipant())->getTableName(), - $viewer->getPHID()); - } - if (strlen($this->fulltext)) { $joins[] = qsprintf( $conn_r, @@ -187,15 +171,6 @@ final class ConpherenceThreadQuery return implode(' ', $joins); } - private function shouldJoinForViewer(PhabricatorUser $viewer) { - if ($viewer->isLoggedIn() && - $this->ids === null && - $this->phids === null) { - return true; - } - return false; - } - protected function buildWhereClause(AphrontDatabaseConnection $conn_r) { $where = array(); @@ -222,13 +197,6 @@ final class ConpherenceThreadQuery $this->participantPHIDs); } - if ($this->isRoom !== null) { - $where[] = qsprintf( - $conn_r, - 'conpherence_thread.isRoom = %d', - (int)$this->isRoom); - } - if (strlen($this->fulltext)) { $where[] = qsprintf( $conn_r, @@ -236,17 +204,6 @@ final class ConpherenceThreadQuery $this->fulltext); } - $viewer = $this->getViewer(); - if ($this->shouldJoinForViewer($viewer)) { - $where[] = qsprintf( - $conn_r, - 'conpherence_thread.isRoom = 1 OR v.participantPHID IS NOT NULL'); - } else if ($this->phids === null && $this->ids === null) { - $where[] = qsprintf( - $conn_r, - 'conpherence_thread.isRoom = 1'); - } - return $this->formatWhereClause($where); } diff --git a/src/applications/conpherence/query/ConpherenceThreadSearchEngine.php b/src/applications/conpherence/query/ConpherenceThreadSearchEngine.php index d647248c87..b36c39f9fe 100644 --- a/src/applications/conpherence/query/ConpherenceThreadSearchEngine.php +++ b/src/applications/conpherence/query/ConpherenceThreadSearchEngine.php @@ -4,7 +4,7 @@ final class ConpherenceThreadSearchEngine extends PhabricatorApplicationSearchEngine { public function getResultTypeDescription() { - return pht('Threads'); + return pht('Rooms'); } public function getApplicationClassName() { @@ -20,10 +20,6 @@ final class ConpherenceThreadSearchEngine $saved->setParameter('fulltext', $request->getStr('fulltext')); - $saved->setParameter( - 'threadType', - $request->getStr('threadType')); - return $saved; } @@ -41,21 +37,6 @@ final class ConpherenceThreadSearchEngine $query->withFulltext($fulltext); } - $thread_type = $saved->getParameter('threadType'); - if (idx($this->getTypeOptions(), $thread_type)) { - switch ($thread_type) { - case 'rooms': - $query->withIsRoom(true); - break; - case 'messages': - $query->withIsRoom(false); - break; - case 'both': - $query->withIsRoom(null); - break; - } - } - return $query; } @@ -77,13 +58,7 @@ final class ConpherenceThreadSearchEngine id(new AphrontFormTextControl()) ->setName('fulltext') ->setLabel(pht('Contains Words')) - ->setValue($fulltext)) - ->appendControl( - id(new AphrontFormSelectControl()) - ->setLabel(pht('Type')) - ->setName('threadType') - ->setOptions($this->getTypeOptions()) - ->setValue($saved->getParameter('threadType'))); + ->setValue($fulltext)); } protected function getURI($path) { @@ -99,7 +74,6 @@ final class ConpherenceThreadSearchEngine if ($this->requireViewer()->isLoggedIn()) { $names['participant'] = pht('Joined Rooms'); - $names['messages'] = pht('All Messages'); } return $names; @@ -112,15 +86,8 @@ final class ConpherenceThreadSearchEngine switch ($query_key) { case 'all': - $query->setParameter('threadType', 'rooms'); return $query; case 'participant': - $query->setParameter('threadType', 'rooms'); - return $query->setParameter( - 'participantPHIDs', - array($this->requireViewer()->getPHID())); - case 'messages': - $query->setParameter('threadType', 'messages'); return $query->setParameter( 'participantPHIDs', array($this->requireViewer()->getPHID())); @@ -145,7 +112,7 @@ final class ConpherenceThreadSearchEngine $viewer = $this->requireViewer(); - $policy_objects = ConpherenceThread::loadPolicyObjects( + $policy_objects = ConpherenceThread::loadViewPolicyObjects( $viewer, $conpherences); @@ -192,11 +159,7 @@ final class ConpherenceThreadSearchEngine $title = $conpherence->getDisplayTitle($viewer); $monogram = $conpherence->getMonogram(); - if ($conpherence->getIsRoom()) { - $icon_name = $conpherence->getPolicyIconName($policy_objects); - } else { - $icon_name = 'fa-envelope-o'; - } + $icon_name = $conpherence->getPolicyIconName($policy_objects); $icon = id(new PHUIIconView()) ->setIconFont($icon_name); $item = id(new PHUIObjectItemView()) @@ -256,14 +219,6 @@ final class ConpherenceThreadSearchEngine return $list; } - private function getTypeOptions() { - return array( - 'rooms' => pht('Rooms'), - 'messages' => pht('Messages'), - 'both' => pht('Both'), - ); - } - private function loadContextMessages(array $threads, $fulltext) { $phids = mpull($threads, 'getPHID'); diff --git a/src/applications/conpherence/storage/ConpherenceThread.php b/src/applications/conpherence/storage/ConpherenceThread.php index 2600e719e7..376a83899f 100644 --- a/src/applications/conpherence/storage/ConpherenceThread.php +++ b/src/applications/conpherence/storage/ConpherenceThread.php @@ -9,7 +9,6 @@ final class ConpherenceThread extends ConpherenceDAO protected $title; protected $imagePHIDs = array(); - protected $isRoom = 0; protected $messageCount; protected $recentParticipantPHIDs = array(); protected $mailKey; @@ -24,30 +23,18 @@ final class ConpherenceThread extends ConpherenceDAO private $widgetData = self::ATTACHABLE; private $images = self::ATTACHABLE; - public static function initializeNewThread(PhabricatorUser $sender) { + public static function initializeNewRoom(PhabricatorUser $sender) { + $default_policy = id(new ConpherenceThreadMembersPolicyRule()) + ->getObjectPolicyFullKey(); return id(new ConpherenceThread()) ->setMessageCount(0) ->setTitle('') ->attachParticipants(array()) ->attachFilePHIDs(array()) ->attachImages(array()) - ->setViewPolicy(PhabricatorPolicies::POLICY_USER) - ->setEditPolicy(PhabricatorPolicies::POLICY_USER) - ->setJoinPolicy(PhabricatorPolicies::POLICY_USER); - } - - public static function initializeNewRoom(PhabricatorUser $creator) { - - return id(new ConpherenceThread()) - ->setIsRoom(1) - ->setMessageCount(0) - ->setTitle('') - ->attachParticipants(array()) - ->attachFilePHIDs(array()) - ->attachImages(array()) - ->setViewPolicy(PhabricatorPolicies::POLICY_USER) - ->setEditPolicy($creator->getPHID()) - ->setJoinPolicy(PhabricatorPolicies::POLICY_USER); + ->setViewPolicy($default_policy) + ->setEditPolicy($default_policy) + ->setJoinPolicy($default_policy); } protected function getConfiguration() { @@ -59,15 +46,11 @@ final class ConpherenceThread extends ConpherenceDAO ), self::CONFIG_COLUMN_SCHEMA => array( 'title' => 'text255?', - 'isRoom' => 'bool', 'messageCount' => 'uint64', 'mailKey' => 'text20', 'joinPolicy' => 'policy', ), self::CONFIG_KEY_SCHEMA => array( - 'key_room' => array( - 'columns' => array('isRoom', 'dateModified'), - ), 'key_phid' => null, 'phid' => array( 'columns' => array('phid'), @@ -214,7 +197,7 @@ final class ConpherenceThread extends ConpherenceDAO return $title; } - return pht('Private Correspondence'); + return pht('Private Room'); } /** @@ -382,15 +365,13 @@ final class ConpherenceThread extends ConpherenceDAO } public function getPolicy($capability) { - if ($this->getIsRoom()) { - switch ($capability) { - case PhabricatorPolicyCapability::CAN_VIEW: - return $this->getViewPolicy(); - case PhabricatorPolicyCapability::CAN_EDIT: - return $this->getEditPolicy(); - case PhabricatorPolicyCapability::CAN_JOIN: - return $this->getJoinPolicy(); - } + switch ($capability) { + case PhabricatorPolicyCapability::CAN_VIEW: + return $this->getViewPolicy(); + case PhabricatorPolicyCapability::CAN_EDIT: + return $this->getEditPolicy(); + case PhabricatorPolicyCapability::CAN_JOIN: + return $this->getJoinPolicy(); } return PhabricatorPolicies::POLICY_NOONE; } @@ -401,12 +382,10 @@ final class ConpherenceThread extends ConpherenceDAO return true; } - if ($this->getIsRoom()) { - switch ($capability) { - case PhabricatorPolicyCapability::CAN_EDIT: - case PhabricatorPolicyCapability::CAN_JOIN: - return false; - } + switch ($capability) { + case PhabricatorPolicyCapability::CAN_EDIT: + case PhabricatorPolicyCapability::CAN_JOIN: + return false; } $participants = $this->getParticipants(); @@ -414,35 +393,28 @@ final class ConpherenceThread extends ConpherenceDAO } public function describeAutomaticCapability($capability) { - if ($this->getIsRoom()) { - switch ($capability) { - case PhabricatorPolicyCapability::CAN_VIEW: - return pht('Participants in a room can always view it.'); - break; - } - } else { - return pht('Participants in a thread can always view and edit it.'); + switch ($capability) { + case PhabricatorPolicyCapability::CAN_VIEW: + return pht('Participants in a room can always view it.'); + break; } } - public static function loadPolicyObjects( + public static function loadViewPolicyObjects( PhabricatorUser $viewer, array $conpherences) { assert_instances_of($conpherences, __CLASS__); - $grouped = mgroup($conpherences, 'getIsRoom'); - $rooms = idx($grouped, 1, array()); - $policies = array(); - foreach ($rooms as $room) { - $policies[] = $room->getViewPolicy(); + foreach ($conpherences as $room) { + $policies[$room->getViewPolicy()] = 1; } $policy_objects = array(); if ($policies) { $policy_objects = id(new PhabricatorPolicyQuery()) ->setViewer($viewer) - ->withPHIDs($policies) + ->withPHIDs(array_keys($policies)) ->execute(); } @@ -452,13 +424,7 @@ final class ConpherenceThread extends ConpherenceDAO public function getPolicyIconName(array $policy_objects) { assert_instances_of($policy_objects, 'PhabricatorPolicy'); - if ($this->getIsRoom()) { - $icon = $policy_objects[$this->getViewPolicy()]->getIcon(); - } else if (count($this->getRecentParticipantPHIDs()) > 2) { - $icon = 'fa-users'; - } else { - $icon = 'fa-user'; - } + $icon = $policy_objects[$this->getViewPolicy()]->getIcon(); return $icon; } diff --git a/src/applications/conpherence/storage/ConpherenceTransaction.php b/src/applications/conpherence/storage/ConpherenceTransaction.php index d4af549d37..ba49cdf9b4 100644 --- a/src/applications/conpherence/storage/ConpherenceTransaction.php +++ b/src/applications/conpherence/storage/ConpherenceTransaction.php @@ -63,11 +63,7 @@ final class ConpherenceTransaction extends PhabricatorApplicationTransaction { case PhabricatorTransactions::TYPE_EDIT_POLICY: case PhabricatorTransactions::TYPE_JOIN_POLICY: case self::TYPE_PICTURE: - if ($this->getObject()->getIsRoom()) { - return $this->getRoomTitle(); - } else { - return $this->getThreadTitle(); - } + return $this->getRoomTitle(); break; case self::TYPE_FILES: $add = array_diff($new, $old); @@ -180,62 +176,6 @@ final class ConpherenceTransaction extends PhabricatorApplicationTransaction { } } - private function getThreadTitle() { - $author_phid = $this->getAuthorPHID(); - - $old = $this->getOldValue(); - $new = $this->getNewValue(); - - switch ($this->getTransactionType()) { - case self::TYPE_TITLE: - if ($old && $new) { - $title = pht( - '%s renamed this thread from "%s" to "%s".', - $this->renderHandleLink($author_phid), - $old, - $new); - } else if ($old) { - $title = pht( - '%s deleted the thread name "%s".', - $this->renderHandleLink($author_phid), - $old); - } else { - $title = pht( - '%s named this thread "%s".', - $this->renderHandleLink($author_phid), - $new); - } - return $title; - break; - case self::TYPE_PICTURE: - return pht( - '%s updated the room image.', - $this->renderHandleLink($author_phid)); - break; - case PhabricatorTransactions::TYPE_VIEW_POLICY: - return pht( - '%s changed the visibility of this thread from "%s" to "%s".', - $this->renderHandleLink($author_phid), - $this->renderPolicyName($old, 'old'), - $this->renderPolicyName($new, 'new')); - break; - case PhabricatorTransactions::TYPE_EDIT_POLICY: - return pht( - '%s changed the edit policy of this thread from "%s" to "%s".', - $this->renderHandleLink($author_phid), - $this->renderPolicyName($old, 'old'), - $this->renderPolicyName($new, 'new')); - break; - case PhabricatorTransactions::TYPE_JOIN_POLICY: - return pht( - '%s changed the join policy of this thread from "%s" to "%s".', - $this->renderHandleLink($author_phid), - $this->renderPolicyName($old, 'old'), - $this->renderPolicyName($new, 'new')); - break; - } - } - public function getRequiredHandlePHIDs() { $phids = parent::getRequiredHandlePHIDs(); diff --git a/src/applications/conpherence/view/ConpherenceDurableColumnView.php b/src/applications/conpherence/view/ConpherenceDurableColumnView.php index f52f48c8e6..032b57291d 100644 --- a/src/applications/conpherence/view/ConpherenceDurableColumnView.php +++ b/src/applications/conpherence/view/ConpherenceDurableColumnView.php @@ -119,21 +119,9 @@ final class ConpherenceDurableColumnView extends AphrontTagView { 'quicksandConfig' => $this->getQuicksandConfig(), )); - $policies = array(); - $conpherences = $this->getConpherences(); - foreach ($conpherences as $conpherence) { - if (!$conpherence->getIsRoom()) { - continue; - } - $policies[] = $conpherence->getViewPolicy(); - } - $policy_objects = array(); - if ($policies) { - $policy_objects = id(new PhabricatorPolicyQuery()) - ->setViewer($this->getUser()) - ->withPHIDs($policies) - ->execute(); - } + $policy_objects = ConpherenceThread::loadViewPolicyObjects( + $this->getUser(), + $this->getConpherences()); $this->setPolicyObjects($policy_objects); $classes = array(); @@ -224,13 +212,10 @@ final class ConpherenceDurableColumnView extends AphrontTagView { assert_instances_of($policy_objects, 'PhabricatorPolicy'); - $icon = null; - if ($conpherence->getIsRoom()) { - $icon = $conpherence->getPolicyIconName($policy_objects); - $icon = id(new PHUIIconView()) - ->addClass('mmr') - ->setIconFont($icon); - } + $icon = $conpherence->getPolicyIconName($policy_objects); + $icon = id(new PHUIIconView()) + ->addClass('mmr') + ->setIconFont($icon); return $icon; } @@ -391,11 +376,6 @@ final class ConpherenceDurableColumnView extends AphrontTagView { } private function getHeaderActionsConfig(ConpherenceThread $conpherence) { - if ($conpherence->getIsRoom()) { - $rename_label = pht('Edit Room'); - } else { - $rename_label = pht('Rename Thread'); - } $can_edit = PhabricatorPolicyFilter::hasCapability( $this->getUser(), $conpherence, @@ -410,7 +390,7 @@ final class ConpherenceDurableColumnView extends AphrontTagView { 'key' => ConpherenceUpdateActions::ADD_PERSON, ), array( - 'name' => $rename_label, + 'name' => pht('Edit Room'), 'disabled' => !$can_edit, 'href' => '/conpherence/update/'.$conpherence->getID().'/?nopic', 'icon' => 'fa-pencil', @@ -445,7 +425,7 @@ final class ConpherenceDurableColumnView extends AphrontTagView { array( 'class' => 'mmb', ), - pht('You do not have any messages yet.')), + pht('You are not in any rooms yet.')), javelin_tag( 'a', array( @@ -453,7 +433,7 @@ final class ConpherenceDurableColumnView extends AphrontTagView { 'class' => 'button grey', 'sigil' => 'workflow', ), - pht('Send a Message')), + pht('Create a Room')), ); } diff --git a/src/applications/conpherence/view/ConpherenceLayoutView.php b/src/applications/conpherence/view/ConpherenceLayoutView.php index 120645e6f4..31b0d3df29 100644 --- a/src/applications/conpherence/view/ConpherenceLayoutView.php +++ b/src/applications/conpherence/view/ConpherenceLayoutView.php @@ -147,7 +147,7 @@ final class ConpherenceLayoutView extends AphrontView { array( 'class' => 'text', ), - pht('You do not have any messages yet.')), + pht('You are not in any rooms yet.')), javelin_tag( 'a', array( @@ -155,7 +155,7 @@ final class ConpherenceLayoutView extends AphrontView { 'class' => 'button grey', 'sigil' => 'workflow', ), - pht('Send a Message')), + pht('Create a Room')), )), javelin_tag( 'div', diff --git a/src/applications/conpherence/view/ConpherenceThreadListView.php b/src/applications/conpherence/view/ConpherenceThreadListView.php index be8c6e4558..668e6f9558 100644 --- a/src/applications/conpherence/view/ConpherenceThreadListView.php +++ b/src/applications/conpherence/view/ConpherenceThreadListView.php @@ -2,7 +2,7 @@ final class ConpherenceThreadListView extends AphrontView { - const SEE_MORE_LIMIT = 5; + const SEE_MORE_LIMIT = 15; private $baseURI; private $threads; @@ -25,40 +25,25 @@ final class ConpherenceThreadListView extends AphrontView { ->addClass('conpherence-menu') ->setID('conpherence-menu'); - $policy_objects = ConpherenceThread::loadPolicyObjects( + $policy_objects = ConpherenceThread::loadViewPolicyObjects( $this->getUser(), $this->threads); - $grouped = mgroup($this->threads, 'getIsRoom'); - $rooms = idx($grouped, 1, array()); - $this->addRoomsToMenu($menu, $rooms, $policy_objects); - $messages = idx($grouped, 0, array()); - $this->addMessagesToMenu($menu, $messages); + $this->addRoomsToMenu($menu, $this->threads, $policy_objects); return $menu; } - public function renderSingleThread(ConpherenceThread $thread) { - $policy_objects = id(new PhabricatorPolicyQuery()) - ->setViewer($this->getUser()) - ->setObject($thread) - ->execute(); + public function renderSingleThread( + ConpherenceThread $thread, + array $policy_objects) { + assert_instances_of($policy_objects, 'PhabricatorPolicy'); return $this->renderThread($thread, $policy_objects); } - public function renderThreadsHTML() { - $thread_html = array(); - - foreach ($this->threads as $thread) { - $thread_html[] = $this->renderSingleThread($thread); - } - - return phutil_implode_html('', $thread_html); - } - private function renderThreadItem( ConpherenceThread $thread, - $policy_objects = array()) { + array $policy_objects) { return id(new PHUIListItemView()) ->setType(PHUIListItemView::TYPE_CUSTOM) ->setName($this->renderThread($thread, $policy_objects)); @@ -72,12 +57,9 @@ final class ConpherenceThreadListView extends AphrontView { $uri = '/'.$thread->getMonogram(); $data = $thread->getDisplayData($user); - $icon = null; - if ($thread->getIsRoom()) { - $icon = id(new PHUIIconView()) - ->addClass('msr') - ->setIconFont($thread->getPolicyIconName($policy_objects)); - } + $icon = id(new PHUIIconView()) + ->addClass('msr') + ->setIconFont($thread->getPolicyIconName($policy_objects)); $title = phutil_tag( 'span', array(), @@ -141,7 +123,7 @@ final class ConpherenceThreadListView extends AphrontView { $create_item = id(new PHUIListItemView()) ->setType(PHUIListItemView::TYPE_LINK) - ->setHref('/conpherence/room/new/') + ->setHref('/conpherence/new/') ->setWorkflow(true) ->setName(pht('Create a Room')); $menu->addMenuItem($create_item); @@ -153,25 +135,6 @@ final class ConpherenceThreadListView extends AphrontView { return $menu; } - private function addMessagesToMenu( - PHUIListView $menu, - array $conpherences) { - - $header = $this->renderMenuItemHeader( - pht('Messages'), - 'conpherence-message-list-header'); - $menu->addMenuItem($header); - - if (empty($conpherences)) { - $menu->addMenuItem($this->getNoMessagesMenuItem()); - return $menu; - } - - $this->addThreadsToMenu($menu, $conpherences, array()); - - return $menu; - } - private function addThreadsToMenu( PHUIListView $menu, array $threads, @@ -187,21 +150,14 @@ final class ConpherenceThreadListView extends AphrontView { $more_threads = array_slice($threads, self::SEE_MORE_LIMIT); } - $is_room = false; foreach ($show_threads as $thread) { $item = $this->renderThreadItem($thread, $policy_objects); $menu->addMenuItem($item); - $is_room = $thread->getIsRoom(); } if ($more_threads) { - if ($is_room) { - $search_uri = '/conpherence/search/query/participant/'; - $sigil = 'more-room'; - } else { - $search_uri = '/conpherence/search/query/messages/'; - $sigil = 'more-message'; - } + $search_uri = '/conpherence/search/query/participant/'; + $sigil = 'more-room'; $more_item = id(new PHUIListItemView()) ->setType(PHUIListItemView::TYPE_LINK) @@ -251,19 +207,6 @@ final class ConpherenceThreadListView extends AphrontView { return $item; } - private function getNoMessagesMenuItem() { - $message = phutil_tag( - 'div', - array( - 'class' => 'no-conpherences-menu-item', - ), - pht('No Messages')); - - return id(new PHUIListItemView()) - ->setType(PHUIListItemView::TYPE_CUSTOM) - ->setName($message); - } - private function getNoRoomsMenuItem() { $message = phutil_tag( 'div', diff --git a/src/applications/people/controller/PhabricatorPeopleProfileController.php b/src/applications/people/controller/PhabricatorPeopleProfileController.php index 8404e56d91..88880a4ae3 100644 --- a/src/applications/people/controller/PhabricatorPeopleProfileController.php +++ b/src/applications/people/controller/PhabricatorPeopleProfileController.php @@ -136,7 +136,8 @@ final class PhabricatorPeopleProfileController $class = 'PhabricatorConpherenceApplication'; if (PhabricatorApplication::isClassInstalledForViewer($class, $viewer)) { - $href = '/conpherence/new/?participant='.$user->getPHID(); + $href = id(new PhutilURI('/conpherence/new/')) + ->setQueryParam('participant', $user->getPHID()); $image = id(new PHUIIconView()) ->setIconFont('fa-comments'); $button = id(new PHUIButtonView()) diff --git a/webroot/rsrc/js/application/conpherence/behavior-widget-pane.js b/webroot/rsrc/js/application/conpherence/behavior-widget-pane.js index 227db56907..77839e9da0 100644 --- a/webroot/rsrc/js/application/conpherence/behavior-widget-pane.js +++ b/webroot/rsrc/js/application/conpherence/behavior-widget-pane.js @@ -321,6 +321,7 @@ JX.behavior('conpherence-widget-pane', function(config) { }); } }); + threadManager.syncWorkflow(workflow, 'submit'); } ); @@ -331,9 +332,25 @@ JX.behavior('conpherence-widget-pane', function(config) { function (e) { var href = config.widgetBaseUpdateURI + _loadedWidgetsID + '/'; var data = e.getNodeData('remove-person'); - // we end up re-directing to conpherence home + + // While the user is removing themselves, disable the notification + // update behavior. If we don't do this, the user can get an error + // when they remove themselves about permissions as the notification + // code tries to load what jist happened. + var threadManager = JX.ConpherenceThreadManager.getInstance(); + var loadedPhid = threadManager.getLoadedThreadPHID(); + threadManager.setLoadedThreadPHID(null); + new JX.Workflow(href, data) - .start(); + .setCloseHandler(function() { + threadManager.setLoadedThreadPHID(loadedPhid); + }) + // we re-direct to conpherence home so the thread manager will + // fix itself there + .setHandler(function(r) { + JX.$U(r.href).go(); + }) + .start(); } ); From 6cfbf481a5f6ae5f32887f851c9253523c355bd9 Mon Sep 17 00:00:00 2001 From: epriestley Date: Thu, 25 Jun 2015 13:57:19 -0700 Subject: [PATCH 2/2] Provide more detailed guidance on upgrading Phabricator and the "stable" branch Summary: Maintaining "stable" is worthwhile now that we're running the cluster, so document its existence. Test Plan: Reading. Reviewers: btrahan Reviewed By: btrahan Subscribers: epriestley Differential Revision: https://secure.phabricator.com/D13446 --- src/docs/user/installation_guide.diviner | 19 +--- src/docs/user/upgrading.diviner | 130 +++++++++++++++++++++++ 2 files changed, 133 insertions(+), 16 deletions(-) create mode 100644 src/docs/user/upgrading.diviner diff --git a/src/docs/user/installation_guide.diviner b/src/docs/user/installation_guide.diviner index 615ad63fda..4df177540e 100644 --- a/src/docs/user/installation_guide.diviner +++ b/src/docs/user/installation_guide.diviner @@ -167,23 +167,10 @@ If it doesn't show up, add: ..to "/etc/php.d/apc.ini" or the "php.ini" file indicated by "php -i". -= Updating Phabricator = - -Since Phabricator is under active development, you should update frequently. To -update Phabricator: - - - Stop the webserver (including `php-fpm`, if you use it). - - Run `git pull` in `libphutil/`, `arcanist/` and `phabricator/`. - - Run `phabricator/bin/storage upgrade`. - - Restart the webserver (and `php-fpm`, if you stopped it earlier). - -For more details, see @{article:Configuration Guide}. You can use a script -similar to this one to automate the process: - -http://www.phabricator.com/rsrc/install/update_phabricator.sh - = Next Steps = Continue by: - - configuring Phabricator with the @{article:Configuration Guide}. + - configuring Phabricator with the @{article:Configuration Guide}; or + - learning how to keep Phabricator up to date with + @{article:Upgrading Phabricator}. diff --git a/src/docs/user/upgrading.diviner b/src/docs/user/upgrading.diviner new file mode 100644 index 0000000000..e8b7228ade --- /dev/null +++ b/src/docs/user/upgrading.diviner @@ -0,0 +1,130 @@ +@title Upgrading Phabricator +@group intro + +This document contains instructions for keeping Phabricator up to date. + +Overview +======== + +Phabricator is under active development, and new features are released +continuously. Staying up to date will keep your install secure. + +We recommend installs upgrade regularly (every 1-2 weeks). Upgrades usually go +smoothly and complete in a few minutes. If you put off upgrades for a long +time, it may take a lot more work to bring things up to date if you want access +to a useful new feature or an important security change. + + +Staying On Top of Changes +========================= + +We release a weekly [[https://secure.phabricator.com/w/changelog | Changelog]], +which describes changes in the previous week. You can look at the changelogs +for an idea of what new features are available, upcoming changes, security +information, and warnings about compatibility issues or migrations. + + +Stable Branch +============= + +You can either run the `master` or `stable` branch of Phabricator. The `stable` +branch is run in the [[ https://phacility.com | Phacility Cluster ]], and lags +about a week behind `master`. + +The `stable` branch is a little more stable than `master`, and may be helpful +if you administrate a larger install. + +We promote `master` to `stable` about once a week, then publish the changelog +and deploy the cluster. During the week, major bugfixes are cherry-picked to +the `stable` branch. The changelog lists the `stable` hashes for that week, +as well as any fixes which were cherry-picked. + +To switch to `stable`, check the branch out in each working copy: + + phabricator/ $ git checkout stable + arcanist/ $ git checkout stable + libphutil/ $ git checkout stable + +You can now follow the upgrade process normally. + + +Upgrade Process +=============== + +IMPORTANT: You **MUST** restart Apache or PHP-FPM after upgrading. + +Phabricator runs on many different systems, with many different webservers. +Given this diversity, we don't currently maintain a comprehensive upgrade +script which can work on any system. However, the general steps are the same +on every system: + + - Stop the webserver (including `php-fpm`, if you use it). + - Stop the daemons, with `phabricator/bin/phd stop`. + - Run `git pull` in `libphutil/`, `arcanist/` and `phabricator/`. + - Run `phabricator/bin/storage upgrade`. + - Start the daemons, with `phabricator/bin/phd start`. + - Restart the webserver (and `php-fpm`, if you stopped it earlier). + +For some more discussion details, see @{article:Configuration Guide}. + +This template script roughly outlines the steps required to upgrade Phabricator. +You'll need to adjust paths and commands a bit for your particular system: + +```lang=sh +#!/bin/sh + +set -e +set -x + +# This is an example script for updating Phabricator, similar to the one used to +# update . It might not work perfectly on your +# system, but hopefully it should be easy to adapt. This script is not intended +# to work without modifications. + +# NOTE: This script assumes you are running it from a directory which contains +# arcanist/, libphutil/, and phabricator/. + +ROOT=`pwd` # You can hard-code the path here instead. + +### UPDATE WORKING COPIES ###################################################### + +cd $ROOT/libphutil +git pull + +cd $ROOT/arcanist +git pull + +cd $ROOT/phabricator +git pull + + +### CYCLE WEB SERVER AND DAEMONS ############################################### + +# Stop daemons. +$ROOT/phabricator/bin/phd stop + +# If running the notification server, stop it. +# $ROOT/phabricator/bin/aphlict stop + +# Stop the webserver (apache, nginx, lighttpd, etc). This command will differ +# depending on which system and webserver you are running: replace it with an +# appropriate command for your system. +# NOTE: If you're running php-fpm, you should stop it here too. + +sudo /etc/init.d/httpd stop + + +# Upgrade the database schema. You may want to add the "--force" flag to allow +# this script to run noninteractively. +$ROOT/phabricator/bin/storage upgrade + +# Restart the webserver. As above, this depends on your system and webserver. +# NOTE: If you're running php-fpm, restart it here too. +sudo /etc/init.d/httpd start + +# Restart daemons. +$ROOT/phabricator/bin/phd start + +# If running the notification server, start it. +# $ROOT/phabricator/bin/aphlict start +```