1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-11-18 12:52:42 +01:00

Merge branch 'master' into redesign-2015

This commit is contained in:
epriestley 2015-06-25 13:59:08 -07:00
commit 26a007f879
33 changed files with 395 additions and 751 deletions

View file

@ -341,7 +341,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',
@ -548,7 +548,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',
@ -1511,19 +1511,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',
@ -1771,6 +1758,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',

View file

@ -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;

View file

@ -0,0 +1,2 @@
ALTER TABLE {$NAMESPACE}_conpherence.conpherence_thread
DROP KEY `key_room`;

View file

@ -0,0 +1,2 @@
ALTER TABLE {$NAMESPACE}_conpherence.conpherence_thread
DROP COLUMN isRoom;

View file

@ -241,7 +241,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',
@ -266,7 +265,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',
@ -3614,7 +3612,6 @@ phutil_register_library_map(array(
'ConpherenceLayoutView' => 'AphrontView',
'ConpherenceListController' => 'ConpherenceController',
'ConpherenceMenuItemView' => 'AphrontTagView',
'ConpherenceNewController' => 'ConpherenceController',
'ConpherenceNewRoomController' => 'ConpherenceController',
'ConpherenceNotificationPanelController' => 'ConpherenceController',
'ConpherenceParticipant' => 'ConpherenceDAO',
@ -3645,7 +3642,6 @@ phutil_register_library_map(array(
'ConpherenceThreadQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
'ConpherenceThreadRemarkupRule' => 'PhabricatorObjectRemarkupRule',
'ConpherenceThreadSearchEngine' => 'PhabricatorApplicationSearchEngine',
'ConpherenceThreadTestCase' => 'ConpherenceTestCase',
'ConpherenceTransaction' => 'PhabricatorApplicationTransaction',
'ConpherenceTransactionComment' => 'PhabricatorApplicationTransactionComment',
'ConpherenceTransactionQuery' => 'PhabricatorApplicationTransactionQuery',

View file

@ -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(

View file

@ -1,169 +0,0 @@
<?php
final class ConpherenceThreadTestCase extends ConpherenceTestCase {
protected function getPhabricatorTestCaseConfiguration() {
return array(
self::PHABRICATOR_TESTCONFIG_BUILD_STORAGE_FIXTURES => 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;
}
}

View file

@ -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<id>[1-9]\d*)/(?P<messageID>[1-9]\d*)/'
=> 'ConpherenceViewController',
'columnview/' => 'ConpherenceColumnViewController',
'new/' => 'ConpherenceNewController',
'room/new/' => 'ConpherenceNewRoomController',
'new/' => 'ConpherenceNewRoomController',
'search/(?:query/(?P<queryKey>[^/]+)/)?'
=> '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/');

View file

@ -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;

View file

@ -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);

View file

@ -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(
@ -50,20 +50,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;')
@ -80,14 +80,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));

View file

@ -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(

View file

@ -1,90 +0,0 @@
<?php
final class ConpherenceNewController extends ConpherenceController {
public function handleRequest(AphrontRequest $request) {
$user = $request->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);
}
}

View file

@ -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);

View file

@ -83,7 +83,7 @@ final class ConpherenceNotificationPanelController
array(
'href' => '/conpherence/',
),
pht('Messages')),
pht('Rooms')),
$content);
$unread = id(new ConpherenceParticipantCountQuery())

View file

@ -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())

View file

@ -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:

View file

@ -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);
}
}

View file

@ -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);

View file

@ -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())

View file

@ -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() {

View file

@ -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) {

View file

@ -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);
}

View file

@ -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())
@ -260,14 +223,6 @@ final class ConpherenceThreadSearchEngine
return $result;
}
private function getTypeOptions() {
return array(
'rooms' => pht('Rooms'),
'messages' => pht('Messages'),
'both' => pht('Both'),
);
}
private function loadContextMessages(array $threads, $fulltext) {
$phids = mpull($threads, 'getPHID');

View file

@ -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;
}

View file

@ -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();

View file

@ -118,21 +118,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();
@ -223,13 +211,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;
}
@ -390,11 +375,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,
@ -409,7 +389,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',
@ -444,7 +424,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(
@ -452,7 +432,7 @@ final class ConpherenceDurableColumnView extends AphrontTagView {
'class' => 'button grey',
'sigil' => 'workflow',
),
pht('Send a Message')),
pht('Create a Room')),
);
}

View file

@ -137,7 +137,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(
@ -145,7 +145,7 @@ final class ConpherenceLayoutView extends AphrontView {
'class' => 'button grey',
'sigil' => 'workflow',
),
pht('Send a Message')),
pht('Create a Room')),
)),
javelin_tag(
'div',

View file

@ -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',

View file

@ -64,7 +64,9 @@ 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());
$actions->addAction(
id(new PhabricatorActionView())
->setIcon('fa-comments')

View file

@ -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}.

View file

@ -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 <https://secure.phabricator.com/>. 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
```

View file

@ -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();
}
);