mirror of
https://we.phorge.it/source/phorge.git
synced 2025-01-11 15:21:03 +01:00
Update PhrictionSearchEngine, implement Projects
Summary: Implements new search engine, projects into Phriction. Test Plan: Test new search choices, add project to Phriction page. Verify hierarchy still works, setting policy works, etc. Reviewers: epriestley Reviewed By: epriestley Subscribers: Luke081515.2, Korvin Maniphest Tasks: T9622 Differential Revision: https://secure.phabricator.com/D14652
This commit is contained in:
parent
8d048f06ab
commit
8b4398f916
6 changed files with 86 additions and 125 deletions
|
@ -9359,8 +9359,9 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorFlaggableInterface',
|
'PhabricatorFlaggableInterface',
|
||||||
'PhabricatorTokenReceiverInterface',
|
'PhabricatorTokenReceiverInterface',
|
||||||
'PhabricatorDestructibleInterface',
|
'PhabricatorDestructibleInterface',
|
||||||
'PhabricatorApplicationTransactionInterface',
|
|
||||||
'PhabricatorFulltextInterface',
|
'PhabricatorFulltextInterface',
|
||||||
|
'PhabricatorProjectInterface',
|
||||||
|
'PhabricatorApplicationTransactionInterface',
|
||||||
),
|
),
|
||||||
'PhrictionDocumentAuthorHeraldField' => 'PhrictionDocumentHeraldField',
|
'PhrictionDocumentAuthorHeraldField' => 'PhrictionDocumentHeraldField',
|
||||||
'PhrictionDocumentContentHeraldField' => 'PhrictionDocumentHeraldField',
|
'PhrictionDocumentContentHeraldField' => 'PhrictionDocumentHeraldField',
|
||||||
|
|
|
@ -9,6 +9,7 @@ final class PhrictionEditController
|
||||||
|
|
||||||
$current_version = null;
|
$current_version = null;
|
||||||
if ($id) {
|
if ($id) {
|
||||||
|
$is_new = false;
|
||||||
$document = id(new PhrictionDocumentQuery())
|
$document = id(new PhrictionDocumentQuery())
|
||||||
->setViewer($viewer)
|
->setViewer($viewer)
|
||||||
->withIDs(array($id))
|
->withIDs(array($id))
|
||||||
|
@ -54,9 +55,11 @@ final class PhrictionEditController
|
||||||
if ($document) {
|
if ($document) {
|
||||||
$content = $document->getContent();
|
$content = $document->getContent();
|
||||||
$current_version = $content->getVersion();
|
$current_version = $content->getVersion();
|
||||||
|
$is_new = false;
|
||||||
} else {
|
} else {
|
||||||
$document = PhrictionDocument::initializeNewDocument($viewer, $slug);
|
$document = PhrictionDocument::initializeNewDocument($viewer, $slug);
|
||||||
$content = $document->getContent();
|
$content = $document->getContent();
|
||||||
|
$is_new = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -91,11 +94,7 @@ final class PhrictionEditController
|
||||||
$draft_note->setSeverity(PHUIInfoView::SEVERITY_NOTICE);
|
$draft_note->setSeverity(PHUIInfoView::SEVERITY_NOTICE);
|
||||||
$draft_note->setTitle(pht('Recovered Draft'));
|
$draft_note->setTitle(pht('Recovered Draft'));
|
||||||
$draft_note->appendChild(
|
$draft_note->appendChild(
|
||||||
hsprintf(
|
pht('Showing a saved draft of your edits, you can %s.', $discard));
|
||||||
'<p>%s</p>',
|
|
||||||
pht(
|
|
||||||
'Showing a saved draft of your edits, you can %s.',
|
|
||||||
$discard)));
|
|
||||||
} else {
|
} else {
|
||||||
$content_text = $content->getContent();
|
$content_text = $content->getContent();
|
||||||
$draft_note = null;
|
$draft_note = null;
|
||||||
|
@ -112,6 +111,15 @@ final class PhrictionEditController
|
||||||
$v_cc = PhabricatorSubscribersQuery::loadSubscribersForPHID(
|
$v_cc = PhabricatorSubscribersQuery::loadSubscribersForPHID(
|
||||||
$document->getPHID());
|
$document->getPHID());
|
||||||
|
|
||||||
|
if ($is_new) {
|
||||||
|
$v_projects = array();
|
||||||
|
} else {
|
||||||
|
$v_projects = PhabricatorEdgeQuery::loadDestinationPHIDs(
|
||||||
|
$document->getPHID(),
|
||||||
|
PhabricatorProjectObjectHasProjectEdgeType::EDGECONST);
|
||||||
|
$v_projects = array_reverse($v_projects);
|
||||||
|
}
|
||||||
|
|
||||||
if ($request->isFormPost()) {
|
if ($request->isFormPost()) {
|
||||||
|
|
||||||
$title = $request->getStr('title');
|
$title = $request->getStr('title');
|
||||||
|
@ -120,7 +128,8 @@ final class PhrictionEditController
|
||||||
$current_version = $request->getInt('contentVersion');
|
$current_version = $request->getInt('contentVersion');
|
||||||
$v_view = $request->getStr('viewPolicy');
|
$v_view = $request->getStr('viewPolicy');
|
||||||
$v_edit = $request->getStr('editPolicy');
|
$v_edit = $request->getStr('editPolicy');
|
||||||
$v_cc = $request->getArr('cc');
|
$v_cc = $request->getArr('cc');
|
||||||
|
$v_projects = $request->getArr('projects');
|
||||||
|
|
||||||
$xactions = array();
|
$xactions = array();
|
||||||
$xactions[] = id(new PhrictionTransaction())
|
$xactions[] = id(new PhrictionTransaction())
|
||||||
|
@ -139,6 +148,12 @@ final class PhrictionEditController
|
||||||
->setTransactionType(PhabricatorTransactions::TYPE_SUBSCRIBERS)
|
->setTransactionType(PhabricatorTransactions::TYPE_SUBSCRIBERS)
|
||||||
->setNewValue(array('=' => $v_cc));
|
->setNewValue(array('=' => $v_cc));
|
||||||
|
|
||||||
|
$proj_edge_type = PhabricatorProjectObjectHasProjectEdgeType::EDGECONST;
|
||||||
|
$xactions[] = id(new PhrictionTransaction())
|
||||||
|
->setTransactionType(PhabricatorTransactions::TYPE_EDGE)
|
||||||
|
->setMetadataValue('edge:type', $proj_edge_type)
|
||||||
|
->setNewValue(array('=' => array_fuse($v_projects)));
|
||||||
|
|
||||||
$editor = id(new PhrictionTransactionEditor())
|
$editor = id(new PhrictionTransactionEditor())
|
||||||
->setActor($viewer)
|
->setActor($viewer)
|
||||||
->setContentSourceFromRequest($request)
|
->setContentSourceFromRequest($request)
|
||||||
|
@ -230,6 +245,12 @@ final class PhrictionEditController
|
||||||
->setName('content')
|
->setName('content')
|
||||||
->setID('document-textarea')
|
->setID('document-textarea')
|
||||||
->setUser($viewer))
|
->setUser($viewer))
|
||||||
|
->appendControl(
|
||||||
|
id(new AphrontFormTokenizerControl())
|
||||||
|
->setLabel(pht('Projects'))
|
||||||
|
->setName('projects')
|
||||||
|
->setValue($v_projects)
|
||||||
|
->setDatasource(new PhabricatorProjectDatasource()))
|
||||||
->appendControl(
|
->appendControl(
|
||||||
id(new AphrontFormTokenizerControl())
|
id(new AphrontFormTokenizerControl())
|
||||||
->setLabel(pht('Subscribers'))
|
->setLabel(pht('Subscribers'))
|
||||||
|
|
|
@ -80,13 +80,14 @@ final class PhrictionTransactionEditor
|
||||||
public function getTransactionTypes() {
|
public function getTransactionTypes() {
|
||||||
$types = parent::getTransactionTypes();
|
$types = parent::getTransactionTypes();
|
||||||
|
|
||||||
$types[] = PhabricatorTransactions::TYPE_COMMENT;
|
|
||||||
$types[] = PhrictionTransaction::TYPE_TITLE;
|
$types[] = PhrictionTransaction::TYPE_TITLE;
|
||||||
$types[] = PhrictionTransaction::TYPE_CONTENT;
|
$types[] = PhrictionTransaction::TYPE_CONTENT;
|
||||||
$types[] = PhrictionTransaction::TYPE_DELETE;
|
$types[] = PhrictionTransaction::TYPE_DELETE;
|
||||||
$types[] = PhrictionTransaction::TYPE_MOVE_TO;
|
$types[] = PhrictionTransaction::TYPE_MOVE_TO;
|
||||||
$types[] = PhrictionTransaction::TYPE_MOVE_AWAY;
|
$types[] = PhrictionTransaction::TYPE_MOVE_AWAY;
|
||||||
|
|
||||||
|
$types[] = PhabricatorTransactions::TYPE_EDGE;
|
||||||
|
$types[] = PhabricatorTransactions::TYPE_COMMENT;
|
||||||
$types[] = PhabricatorTransactions::TYPE_VIEW_POLICY;
|
$types[] = PhabricatorTransactions::TYPE_VIEW_POLICY;
|
||||||
$types[] = PhabricatorTransactions::TYPE_EDIT_POLICY;
|
$types[] = PhabricatorTransactions::TYPE_EDIT_POLICY;
|
||||||
|
|
||||||
|
|
|
@ -17,8 +17,6 @@ final class PhrictionDocumentQuery
|
||||||
const STATUS_OPEN = 'status-open';
|
const STATUS_OPEN = 'status-open';
|
||||||
const STATUS_NONSTUB = 'status-nonstub';
|
const STATUS_NONSTUB = 'status-nonstub';
|
||||||
|
|
||||||
const ORDER_CREATED = 'order-created';
|
|
||||||
const ORDER_UPDATED = 'order-updated';
|
|
||||||
const ORDER_HIERARCHY = 'order-hierarchy';
|
const ORDER_HIERARCHY = 'order-hierarchy';
|
||||||
|
|
||||||
public function withIDs(array $ids) {
|
public function withIDs(array $ids) {
|
||||||
|
@ -61,38 +59,15 @@ final class PhrictionDocumentQuery
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setOrder($order) {
|
protected function loadPage() {
|
||||||
switch ($order) {
|
return $this->loadStandardPage($this->newResultObject());
|
||||||
case self::ORDER_CREATED:
|
|
||||||
$this->setOrderVector(array('id'));
|
|
||||||
break;
|
|
||||||
case self::ORDER_UPDATED:
|
|
||||||
$this->setOrderVector(array('updated'));
|
|
||||||
break;
|
|
||||||
case self::ORDER_HIERARCHY:
|
|
||||||
$this->setOrderVector(array('depth', 'title', 'updated'));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
throw new Exception(pht('Unknown order "%s".', $order));
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function loadPage() {
|
public function newResultObject() {
|
||||||
$table = new PhrictionDocument();
|
return new PhrictionDocument();
|
||||||
$conn_r = $table->establishConnection('r');
|
}
|
||||||
|
|
||||||
$rows = queryfx_all(
|
protected function willFilterPage(array $documents) {
|
||||||
$conn_r,
|
|
||||||
'SELECT d.* FROM %T d %Q %Q %Q %Q',
|
|
||||||
$table->getTableName(),
|
|
||||||
$this->buildJoinClause($conn_r),
|
|
||||||
$this->buildWhereClause($conn_r),
|
|
||||||
$this->buildOrderClause($conn_r),
|
|
||||||
$this->buildLimitClause($conn_r));
|
|
||||||
|
|
||||||
$documents = $table->loadAllFromArray($rows);
|
|
||||||
|
|
||||||
if ($documents) {
|
if ($documents) {
|
||||||
$ancestor_slugs = array();
|
$ancestor_slugs = array();
|
||||||
|
@ -104,6 +79,8 @@ final class PhrictionDocumentQuery
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($ancestor_slugs) {
|
if ($ancestor_slugs) {
|
||||||
|
$table = new PhrictionDocument();
|
||||||
|
$conn_r = $table->establishConnection('r');
|
||||||
$ancestors = queryfx_all(
|
$ancestors = queryfx_all(
|
||||||
$conn_r,
|
$conn_r,
|
||||||
'SELECT * FROM %T WHERE slug IN (%Ls)',
|
'SELECT * FROM %T WHERE slug IN (%Ls)',
|
||||||
|
@ -122,11 +99,6 @@ final class PhrictionDocumentQuery
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $documents;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function willFilterPage(array $documents) {
|
|
||||||
// To view a Phriction document, you must also be able to view all of the
|
// To view a Phriction document, you must also be able to view all of the
|
||||||
// ancestor documents. Filter out documents which have ancestors that are
|
// ancestor documents. Filter out documents which have ancestors that are
|
||||||
// not visible.
|
// not visible.
|
||||||
|
@ -190,58 +162,59 @@ final class PhrictionDocumentQuery
|
||||||
return $documents;
|
return $documents;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function buildJoinClause(AphrontDatabaseConnection $conn) {
|
protected function buildJoinClauseParts(AphrontDatabaseConnection $conn) {
|
||||||
$join = '';
|
$joins = array();
|
||||||
|
|
||||||
if ($this->getOrderVector()->containsKey('updated')) {
|
if ($this->getOrderVector()->containsKey('updated')) {
|
||||||
$content_dao = new PhrictionContent();
|
$content_dao = new PhrictionContent();
|
||||||
$join = qsprintf(
|
$joins[] = qsprintf(
|
||||||
$conn,
|
$conn,
|
||||||
'JOIN %T c ON d.contentID = c.id',
|
'JOIN %T c ON d.contentID = c.id',
|
||||||
$content_dao->getTableName());
|
$content_dao->getTableName());
|
||||||
}
|
}
|
||||||
|
|
||||||
return $join;
|
return $joins;
|
||||||
}
|
}
|
||||||
protected function buildWhereClause(AphrontDatabaseConnection $conn) {
|
|
||||||
$where = array();
|
|
||||||
|
|
||||||
if ($this->ids) {
|
protected function buildWhereClauseParts(AphrontDatabaseConnection $conn) {
|
||||||
|
$where = parent::buildWhereClauseParts($conn);
|
||||||
|
|
||||||
|
if ($this->ids !== null) {
|
||||||
$where[] = qsprintf(
|
$where[] = qsprintf(
|
||||||
$conn,
|
$conn,
|
||||||
'd.id IN (%Ld)',
|
'd.id IN (%Ld)',
|
||||||
$this->ids);
|
$this->ids);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->phids) {
|
if ($this->phids !== null) {
|
||||||
$where[] = qsprintf(
|
$where[] = qsprintf(
|
||||||
$conn,
|
$conn,
|
||||||
'd.phid IN (%Ls)',
|
'd.phid IN (%Ls)',
|
||||||
$this->phids);
|
$this->phids);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->slugs) {
|
if ($this->slugs !== null) {
|
||||||
$where[] = qsprintf(
|
$where[] = qsprintf(
|
||||||
$conn,
|
$conn,
|
||||||
'd.slug IN (%Ls)',
|
'd.slug IN (%Ls)',
|
||||||
$this->slugs);
|
$this->slugs);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->statuses) {
|
if ($this->statuses !== null) {
|
||||||
$where[] = qsprintf(
|
$where[] = qsprintf(
|
||||||
$conn,
|
$conn,
|
||||||
'd.status IN (%Ld)',
|
'd.status IN (%Ld)',
|
||||||
$this->statuses);
|
$this->statuses);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->slugPrefix) {
|
if ($this->slugPrefix !== null) {
|
||||||
$where[] = qsprintf(
|
$where[] = qsprintf(
|
||||||
$conn,
|
$conn,
|
||||||
'd.slug LIKE %>',
|
'd.slug LIKE %>',
|
||||||
$this->slugPrefix);
|
$this->slugPrefix);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->depths) {
|
if ($this->depths !== null) {
|
||||||
$where[] = qsprintf(
|
$where[] = qsprintf(
|
||||||
$conn,
|
$conn,
|
||||||
'd.depth IN (%Ld)',
|
'd.depth IN (%Ld)',
|
||||||
|
@ -274,9 +247,16 @@ final class PhrictionDocumentQuery
|
||||||
throw new Exception(pht("Unknown status '%s'!", $this->status));
|
throw new Exception(pht("Unknown status '%s'!", $this->status));
|
||||||
}
|
}
|
||||||
|
|
||||||
$where[] = $this->buildPagingClause($conn);
|
return $where;
|
||||||
|
}
|
||||||
|
|
||||||
return $this->formatWhereClause($where);
|
public function getBuiltinOrders() {
|
||||||
|
return array(
|
||||||
|
self::ORDER_HIERARCHY => array(
|
||||||
|
'vector' => array('depth', 'title', 'updated'),
|
||||||
|
'name' => pht('Hierarchy'),
|
||||||
|
),
|
||||||
|
) + parent::getBuiltinOrders();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getOrderableColumns() {
|
public function getOrderableColumns() {
|
||||||
|
@ -331,6 +311,9 @@ final class PhrictionDocumentQuery
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected function getPrimaryTableAlias() {
|
||||||
|
return 'd';
|
||||||
|
}
|
||||||
|
|
||||||
public function getQueryApplicationClass() {
|
public function getQueryApplicationClass() {
|
||||||
return 'PhabricatorPhrictionApplication';
|
return 'PhabricatorPhrictionApplication';
|
||||||
|
|
|
@ -11,52 +11,29 @@ final class PhrictionSearchEngine
|
||||||
return 'PhabricatorPhrictionApplication';
|
return 'PhabricatorPhrictionApplication';
|
||||||
}
|
}
|
||||||
|
|
||||||
public function buildSavedQueryFromRequest(AphrontRequest $request) {
|
public function newQuery() {
|
||||||
$saved = new PhabricatorSavedQuery();
|
return id(new PhrictionDocumentQuery())
|
||||||
|
|
||||||
$saved->setParameter('status', $request->getStr('status'));
|
|
||||||
$saved->setParameter('order', $request->getStr('order'));
|
|
||||||
|
|
||||||
return $saved;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function buildQueryFromSavedQuery(PhabricatorSavedQuery $saved) {
|
|
||||||
$query = id(new PhrictionDocumentQuery())
|
|
||||||
->needContent(true)
|
->needContent(true)
|
||||||
->withStatus(PhrictionDocumentQuery::STATUS_NONSTUB);
|
->withStatus(PhrictionDocumentQuery::STATUS_NONSTUB);
|
||||||
|
}
|
||||||
|
|
||||||
$status = $saved->getParameter('status');
|
protected function buildQueryFromParameters(array $map) {
|
||||||
$status = idx($this->getStatusValues(), $status);
|
$query = $this->newQuery();
|
||||||
if ($status) {
|
|
||||||
$query->withStatus($status);
|
|
||||||
}
|
|
||||||
|
|
||||||
$order = $saved->getParameter('order');
|
if ($map['status']) {
|
||||||
$order = idx($this->getOrderValues(), $order);
|
$query->withStatus($map['status']);
|
||||||
if ($order) {
|
|
||||||
$query->setOrder($order);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return $query;
|
return $query;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function buildSearchForm(
|
protected function buildCustomSearchFields() {
|
||||||
AphrontFormView $form,
|
return array(
|
||||||
PhabricatorSavedQuery $saved_query) {
|
id(new PhabricatorSearchSelectField())
|
||||||
|
->setKey('status')
|
||||||
$form
|
->setLabel(pht('Status'))
|
||||||
->appendChild(
|
->setOptions($this->getStatusOptions()),
|
||||||
id(new AphrontFormSelectControl())
|
);
|
||||||
->setLabel(pht('Status'))
|
|
||||||
->setName('status')
|
|
||||||
->setOptions($this->getStatusOptions())
|
|
||||||
->setValue($saved_query->getParameter('status')))
|
|
||||||
->appendChild(
|
|
||||||
id(new AphrontFormSelectControl())
|
|
||||||
->setLabel(pht('Order'))
|
|
||||||
->setName('order')
|
|
||||||
->setOptions($this->getOrderOptions())
|
|
||||||
->setValue($saved_query->getParameter('order')));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function getURI($path) {
|
protected function getURI($path) {
|
||||||
|
@ -66,7 +43,6 @@ final class PhrictionSearchEngine
|
||||||
protected function getBuiltinQueryNames() {
|
protected function getBuiltinQueryNames() {
|
||||||
$names = array(
|
$names = array(
|
||||||
'active' => pht('Active'),
|
'active' => pht('Active'),
|
||||||
'updated' => pht('Updated'),
|
|
||||||
'all' => pht('All'),
|
'all' => pht('All'),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -79,12 +55,11 @@ final class PhrictionSearchEngine
|
||||||
$query->setQueryKey($query_key);
|
$query->setQueryKey($query_key);
|
||||||
|
|
||||||
switch ($query_key) {
|
switch ($query_key) {
|
||||||
case 'active':
|
|
||||||
return $query->setParameter('status', 'active');
|
|
||||||
case 'all':
|
case 'all':
|
||||||
return $query;
|
return $query;
|
||||||
case 'updated':
|
case 'active':
|
||||||
return $query->setParameter('order', 'updated');
|
return $query->setParameter(
|
||||||
|
'status', PhrictionDocumentQuery::STATUS_OPEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
return parent::buildSavedQueryFromBuiltin($query_key);
|
return parent::buildSavedQueryFromBuiltin($query_key);
|
||||||
|
@ -92,29 +67,8 @@ final class PhrictionSearchEngine
|
||||||
|
|
||||||
private function getStatusOptions() {
|
private function getStatusOptions() {
|
||||||
return array(
|
return array(
|
||||||
'active' => pht('Show Active Documents'),
|
PhrictionDocumentQuery::STATUS_OPEN => pht('Show Active Documents'),
|
||||||
'all' => pht('Show All Documents'),
|
PhrictionDocumentQuery::STATUS_NONSTUB => pht('Show All Documents'),
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
private function getStatusValues() {
|
|
||||||
return array(
|
|
||||||
'active' => PhrictionDocumentQuery::STATUS_OPEN,
|
|
||||||
'all' => PhrictionDocumentQuery::STATUS_NONSTUB,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
private function getOrderOptions() {
|
|
||||||
return array(
|
|
||||||
'created' => pht('Date Created'),
|
|
||||||
'updated' => pht('Date Updated'),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
private function getOrderValues() {
|
|
||||||
return array(
|
|
||||||
'created' => PhrictionDocumentQuery::ORDER_CREATED,
|
|
||||||
'updated' => PhrictionDocumentQuery::ORDER_UPDATED,
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,8 +7,9 @@ final class PhrictionDocument extends PhrictionDAO
|
||||||
PhabricatorFlaggableInterface,
|
PhabricatorFlaggableInterface,
|
||||||
PhabricatorTokenReceiverInterface,
|
PhabricatorTokenReceiverInterface,
|
||||||
PhabricatorDestructibleInterface,
|
PhabricatorDestructibleInterface,
|
||||||
PhabricatorApplicationTransactionInterface,
|
PhabricatorFulltextInterface,
|
||||||
PhabricatorFulltextInterface {
|
PhabricatorProjectInterface,
|
||||||
|
PhabricatorApplicationTransactionInterface {
|
||||||
|
|
||||||
protected $slug;
|
protected $slug;
|
||||||
protected $depth;
|
protected $depth;
|
||||||
|
|
Loading…
Reference in a new issue