Page MenuHomestyx hydra

No OneTemporary

diff --git a/src/applications/conpherence/controller/ConpherenceListController.php b/src/applications/conpherence/controller/ConpherenceListController.php
index 80ef89d66a..916d044e86 100644
--- a/src/applications/conpherence/controller/ConpherenceListController.php
+++ b/src/applications/conpherence/controller/ConpherenceListController.php
@@ -1,119 +1,115 @@
<?php
/**
* @group conpherence
*/
final class ConpherenceListController extends
ConpherenceController {
private $conpherenceID;
public function setConpherenceID($conpherence_id) {
$this->conpherenceID = $conpherence_id;
return $this;
}
public function getConpherenceID() {
return $this->conpherenceID;
}
public function willProcessRequest(array $data) {
$this->setConpherenceID(idx($data, 'id'));
}
public function processRequest() {
$request = $this->getRequest();
$user = $request->getUser();
$title = pht('Conpherence');
$conpherence_id = $this->getConpherenceID();
$current_selection_epoch = null;
if ($conpherence_id) {
$conpherence = id(new ConpherenceThreadQuery())
->setViewer($user)
->withIDs(array($conpherence_id))
->executeOne();
if (!$conpherence) {
return new Aphront404Response();
}
if ($conpherence->getTitle()) {
$title = $conpherence->getTitle();
}
$this->setSelectedConpherencePHID($conpherence->getPHID());
- $read_status = ConpherenceParticipationStatus::UP_TO_DATE;
$participant = $conpherence->getParticipant($user->getPHID());
- $write_guard = AphrontWriteGuard::beginScopedUnguardedWrites();
- $participant->markUpToDate();
- unset($write_guard);
$current_selection_epoch = $participant->getDateTouched();
}
$this->loadStartingConpherences($current_selection_epoch);
$nav = $this->buildSideNavView();
$main_pane = $this->renderEmptyMainPane();
$nav->appendChild(
array(
$main_pane,
));
return $this->buildApplicationPage(
$nav,
array(
'title' => $title,
'device' => true,
)
);
}
private function renderEmptyMainPane() {
$this->initJavelinBehaviors();
return phutil_render_tag(
'div',
array(
'id' => 'conpherence-main-pane'
),
phutil_render_tag(
'div',
array(
'class' => 'conpherence-header-pane',
'id' => 'conpherence-header-pane',
),
''
).
phutil_render_tag(
'div',
array(
'class' => 'conpherence-widget-pane',
'id' => 'conpherence-widget-pane'
),
''
).
javelin_render_tag(
'div',
array(
'class' => 'conpherence-message-pane',
'id' => 'conpherence-message-pane'
),
phutil_render_tag(
'div',
array(
'class' => 'conpherence-messages',
'id' => 'conpherence-messages'
),
''
).
phutil_render_tag(
'div',
array(
'id' => 'conpherence-form'
),
''
)
)
);
}
}
diff --git a/src/applications/conpherence/controller/ConpherenceViewController.php b/src/applications/conpherence/controller/ConpherenceViewController.php
index 284d237802..d615edac50 100644
--- a/src/applications/conpherence/controller/ConpherenceViewController.php
+++ b/src/applications/conpherence/controller/ConpherenceViewController.php
@@ -1,295 +1,297 @@
<?php
/**
* @group conpherence
*/
final class ConpherenceViewController extends
ConpherenceController {
private $conpherenceID;
private $conpherence;
public function setConpherence(ConpherenceThread $conpherence) {
$this->conpherence = $conpherence;
return $this;
}
public function getConpherence() {
return $this->conpherence;
}
public function setConpherenceID($conpherence_id) {
$this->conpherenceID = $conpherence_id;
return $this;
}
public function getConpherenceID() {
return $this->conpherenceID;
}
public function willProcessRequest(array $data) {
$this->setConpherenceID(idx($data, 'id'));
}
public function processRequest() {
$request = $this->getRequest();
$user = $request->getUser();
$conpherence_id = $this->getConpherenceID();
if (!$conpherence_id) {
return new Aphront404Response();
}
if (!$request->isAjax()) {
return id(new AphrontRedirectResponse())
->setURI($this->getApplicationURI($conpherence_id.'/'));
}
$conpherence = id(new ConpherenceThreadQuery())
->setViewer($user)
->withIDs(array($conpherence_id))
->needWidgetData(true)
->executeOne();
$this->setConpherence($conpherence);
$participant = $conpherence->getParticipant($user->getPHID());
+ $transactions = $conpherence->getTransactions();
+ $latest_transaction = end($transactions);
$write_guard = AphrontWriteGuard::beginScopedUnguardedWrites();
- $participant->markUpToDate();
+ $participant->markUpToDate($latest_transaction);
unset($write_guard);
$header = $this->renderHeaderPaneContent();
$messages = $this->renderMessagePaneContent();
$widgets = $this->renderWidgetPaneContent();
$content = $header + $widgets + $messages;
return id(new AphrontAjaxResponse())->setContent($content);
}
private function renderHeaderPaneContent() {
require_celerity_resource('conpherence-header-pane-css');
$user = $this->getRequest()->getUser();
$conpherence = $this->getConpherence();
$display_data = $conpherence->getDisplayData($user);
$edit_href = $this->getApplicationURI('update/'.$conpherence->getID().'/');
$header =
javelin_render_tag(
'a',
array(
'class' => 'edit',
'href' => $edit_href,
'sigil' => 'workflow',
),
''
).
phutil_render_tag(
'div',
array(
'class' => 'header-image',
'style' => 'background-image: url('.$display_data['image'].');'
),
''
).
phutil_render_tag(
'div',
array(
'class' => 'title',
),
phutil_escape_html($display_data['title'])
).
phutil_render_tag(
'div',
array(
'class' => 'subtitle',
),
phutil_escape_html($display_data['subtitle'])
);
return array('header' => $header);
}
private function renderMessagePaneContent() {
require_celerity_resource('conpherence-message-pane-css');
$user = $this->getRequest()->getUser();
$conpherence = $this->getConpherence();
$handles = $conpherence->getHandles();
$rendered_transactions = array();
$transactions = $conpherence->getTransactions();
foreach ($transactions as $transaction) {
if ($transaction->shouldHide()) {
continue;
}
$rendered_transactions[] = id(new ConpherenceTransactionView())
->setUser($user)
->setConpherenceTransaction($transaction)
->setHandles($handles)
->render();
}
$transactions = implode(' ', $rendered_transactions);
$form =
id(new AphrontFormView())
->setAction($this->getApplicationURI('update/'.$conpherence->getID().'/'))
->setFlexible(true)
->setUser($user)
->addHiddenInput('action', 'message')
->appendChild(
id(new PhabricatorRemarkupControl())
->setUser($user)
->setName('text')
)
->appendChild(
id(new AphrontFormSubmitControl())
->setValue(pht('Pontificate'))
)->render();
return array(
'messages' => $transactions,
'form' => $form
);
}
private function renderWidgetPaneContent() {
require_celerity_resource('conpherence-widget-pane-css');
Javelin::initBehavior(
'conpherence-widget-pane',
array(
'widgetRegistery' => array(
'widgets-files' => 1,
'widgets-tasks' => 1,
'widgets-calendar' => 1,
)
)
);
$conpherence = $this->getConpherence();
$widgets = phutil_render_tag(
'div',
array(
'class' => 'widgets-header'
),
javelin_render_tag(
'a',
array(
'sigil' => 'conpherence-change-widget',
'meta' => array('widget' => 'widgets-files')
),
pht('Files')
).' | '.
javelin_render_tag(
'a',
array(
'sigil' => 'conpherence-change-widget',
'meta' => array('widget' => 'widgets-tasks')
),
pht('Tasks')
).' | '.
javelin_render_tag(
'a',
array(
'sigil' => 'conpherence-change-widget',
'meta' => array('widget' => 'widgets-calendar')
),
pht('Calendar')
)
).
phutil_render_tag(
'div',
array(
'class' => 'widgets-body',
'id' => 'widgets-files',
'style' => 'display: none;'
),
$this->renderFilesWidgetPaneContent()
).
phutil_render_tag(
'div',
array(
'class' => 'widgets-body',
'id' => 'widgets-tasks',
),
$this->renderTaskWidgetPaneContent()
).
phutil_render_tag(
'div',
array(
'class' => 'widgets-body',
'id' => 'widgets-calendar',
'style' => 'display: none;'
),
$this->renderCalendarWidgetPaneContent()
);
return array('widgets' => $widgets);
}
private function renderFilesWidgetPaneContent() {
$conpherence = $this->getConpherence();
$widget_data = $conpherence->getWidgetData();
$files = $widget_data['files'];
$table_data = array();
foreach ($files as $file) {
$thumb = $file->getThumb60x45URI();
$table_data[] = array(
phutil_render_tag(
'img',
array(
'src' => $thumb
),
''
),
$file->getName()
);
}
$header = id(new PhabricatorHeaderView())
->setHeader(pht('Attached Files'));
$table = id(new AphrontTableView($table_data))
->setNoDataString(pht('No files attached to conpherence.'))
->setHeaders(array('', pht('Name')))
->setColumnClasses(array('', 'wide'));
return $header->render() . $table->render();
}
private function renderTaskWidgetPaneContent() {
$conpherence = $this->getConpherence();
$widget_data = $conpherence->getWidgetData();
$tasks = $widget_data['tasks'];
$priority_map = ManiphestTaskPriority::getTaskPriorityMap();
$handles = $conpherence->getHandles();
$content = array();
foreach ($tasks as $owner_phid => $actual_tasks) {
$handle = $handles[$owner_phid];
$content[] = id(new PhabricatorHeaderView())
->setHeader($handle->getName())
->render();
$actual_tasks = msort($actual_tasks, 'getPriority');
$actual_tasks = array_reverse($actual_tasks);
$data = array();
foreach ($actual_tasks as $task) {
$data[] = array(
idx($priority_map, $task->getPriority(), pht('???')),
phutil_render_tag(
'a',
array(
'href' => '/T'.$task->getID()
),
phutil_escape_html($task->getTitle())
)
);
}
$table = id(new AphrontTableView($data))
->setNoDataString(pht('No open tasks.'))
->setHeaders(array(pht('Pri'), pht('Title')))
->setColumnClasses(array('', 'wide'));
$content[] = $table->render();
}
return implode('', $content);
}
private function renderCalendarWidgetPaneContent() {
$header = id(new PhabricatorHeaderView())
->setHeader(pht('Calendar'));
return $header->render() . 'TODO';
}
}
diff --git a/src/applications/conpherence/storage/ConpherenceParticipant.php b/src/applications/conpherence/storage/ConpherenceParticipant.php
index e21d6204ad..be897c11fe 100644
--- a/src/applications/conpherence/storage/ConpherenceParticipant.php
+++ b/src/applications/conpherence/storage/ConpherenceParticipant.php
@@ -1,27 +1,28 @@
<?php
/**
* @group conpherence
*/
final class ConpherenceParticipant extends ConpherenceDAO {
protected $participantPHID;
protected $conpherencePHID;
protected $participationStatus;
protected $behindTransactionPHID;
protected $dateTouched;
- public function markUpToDate() {
+ public function markUpToDate(ConpherenceTransaction $xaction) {
if (!$this->isUpToDate()) {
$this->setParticipationStatus(ConpherenceParticipationStatus::UP_TO_DATE);
+ $this->setBehindTransactionPHID($xaction->getPHID());
$this->save();
}
return $this;
}
public function isUpToDate() {
return $this->getParticipationStatus() ==
ConpherenceParticipationStatus::UP_TO_DATE;
}
}
diff --git a/src/applications/conpherence/storage/ConpherenceThread.php b/src/applications/conpherence/storage/ConpherenceThread.php
index c5c2c4723a..1b80aec1a5 100644
--- a/src/applications/conpherence/storage/ConpherenceThread.php
+++ b/src/applications/conpherence/storage/ConpherenceThread.php
@@ -1,237 +1,240 @@
<?php
/**
* @group conpherence
*/
final class ConpherenceThread extends ConpherenceDAO
implements PhabricatorPolicyInterface {
protected $id;
protected $phid;
protected $title;
protected $imagePHID;
protected $mailKey;
private $participants;
private $transactions;
private $handles;
private $filePHIDs;
private $widgetData;
public function getConfiguration() {
return array(
self::CONFIG_AUX_PHID => true,
) + parent::getConfiguration();
}
public function generatePHID() {
return PhabricatorPHID::generateNewPHID(
PhabricatorPHIDConstants::PHID_TYPE_CONP);
}
public function save() {
if (!$this->getMailKey()) {
$this->setMailKey(Filesystem::readRandomCharacters(20));
}
return parent::save();
}
public function attachParticipants(array $participants) {
assert_instances_of($participants, 'ConpherenceParticipant');
$this->participants = $participants;
return $this;
}
public function getParticipants() {
if ($this->participants === null) {
throw new Exception(
'You must attachParticipants first!'
);
}
return $this->participants;
}
public function getParticipant($phid) {
$participants = $this->getParticipants();
return $participants[$phid];
}
public function getParticipantPHIDs() {
$participants = $this->getParticipants();
return array_keys($participants);
}
public function attachHandles(array $handles) {
assert_instances_of($handles, 'PhabricatorObjectHandle');
$this->handles = $handles;
return $this;
}
public function getHandles() {
if ($this->handles === null) {
throw new Exception(
'You must attachHandles first!'
);
}
return $this->handles;
}
public function attachTransactions(array $transactions) {
assert_instances_of($transactions, 'ConpherenceTransaction');
$this->transactions = $transactions;
return $this;
}
public function getTransactions() {
if ($this->transactions === null) {
throw new Exception(
'You must attachTransactions first!'
);
}
return $this->transactions;
}
public function attachFilePHIDs(array $file_phids) {
$this->filePHIDs = $file_phids;
return $this;
}
public function getFilePHIDs() {
if ($this->filePHIDs === null) {
throw new Exception(
'You must attachFilePHIDs first!'
);
}
return $this->filePHIDs;
}
public function attachWidgetData(array $widget_data) {
$this->widgetData = $widget_data;
return $this;
}
public function getWidgetData() {
if ($this->widgetData === null) {
throw new Exception(
'You must attachWidgetData first!'
);
}
return $this->widgetData;
}
public function loadImageURI() {
$src_phid = $this->getImagePHID();
if ($src_phid) {
$file = id(new PhabricatorFile())->loadOneWhere('phid = %s', $src_phid);
if ($file) {
return $file->getBestURI();
}
}
return PhabricatorUser::getDefaultProfileImageURI();
}
public function getDisplayData(PhabricatorUser $user) {
$transactions = $this->getTransactions();
$latest_transaction = end($transactions);
$latest_participant = $latest_transaction->getAuthorPHID();
$handles = $this->getHandles();
$latest_handle = $handles[$latest_participant];
if ($this->getImagePHID()) {
$img_src = $this->loadImageURI();
} else {
$img_src = $latest_handle->getImageURI();
}
$title = $this->getTitle();
if (!$title) {
$title = $latest_handle->getName();
unset($handles[$latest_participant]);
}
unset($handles[$user->getPHID()]);
$subtitle = '';
$count = 0;
$final = false;
foreach ($handles as $handle) {
if ($handle->getType() != PhabricatorPHIDConstants::PHID_TYPE_USER) {
continue;
}
if ($subtitle) {
if ($final) {
$subtitle .= '...';
break;
} else {
$subtitle .= ', ';
}
}
$subtitle .= $handle->getName();
$count++;
$final = $count == 3;
}
$participants = $this->getParticipants();
$user_participation = $participants[$user->getPHID()];
$unread_count = 0;
$max_count = 10;
$snippet = null;
if (!$user_participation->isUpToDate()) {
$behind_transaction_phid =
$user_participation->getBehindTransactionPHID();
} else {
$behind_transaction_phid = null;
}
foreach (array_reverse($transactions) as $transaction) {
switch ($transaction->getTransactionType()) {
case ConpherenceTransactionType::TYPE_PARTICIPANTS:
case ConpherenceTransactionType::TYPE_TITLE:
case ConpherenceTransactionType::TYPE_PICTURE:
continue 2;
case PhabricatorTransactions::TYPE_COMMENT:
if ($snippet === null) {
$snippet = phutil_utf8_shorten(
$transaction->getComment()->getContent(),
48
);
}
// fallthrough intentionally here
case ConpherenceTransactionType::TYPE_FILES:
- default:
- if ($behind_transaction_phid &&
- $transaction->getPHID() != $behind_transaction_phid) {
- $unread_count++;
+ if ($behind_transaction_phid) {
+ $unread_count++;
+ if ($transaction->getPHID() == $behind_transaction_phid) {
+ break 2;
}
+ }
if ($unread_count > $max_count) {
break 2;
}
break;
+ default:
+ continue 2;
}
if ($snippet && !$behind_transaction_phid) {
break;
}
}
if ($unread_count > $max_count) {
$unread_count = $max_count.'+';
}
return array(
'title' => $title,
'subtitle' => $subtitle,
'unread_count' => $unread_count,
'epoch' => $latest_transaction->getDateCreated(),
'image' => $img_src,
'snippet' => $snippet,
);
}
/* -( PhabricatorPolicyInterface Implementation )-------------------------- */
public function getCapabilities() {
return array(
PhabricatorPolicyCapability::CAN_VIEW,
PhabricatorPolicyCapability::CAN_EDIT,
);
}
public function getPolicy($capability) {
return PhabricatorPolicies::POLICY_NOONE;
}
public function hasAutomaticCapability($capability, PhabricatorUser $user) {
$participants = $this->getParticipants();
return isset($participants[$user->getPHID()]);
}
}

File Metadata

Mime Type
text/x-diff
Expires
Mon, Jul 28, 8:15 PM (1 w, 4 d ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
187467
Default Alt Text
(19 KB)

Event Timeline