Page MenuHomePhorge

No OneTemporary

diff --git a/src/applications/phriction/query/PhrictionDocumentQuery.php b/src/applications/phriction/query/PhrictionDocumentQuery.php
index 8d35430d64..35b4ee1675 100644
--- a/src/applications/phriction/query/PhrictionDocumentQuery.php
+++ b/src/applications/phriction/query/PhrictionDocumentQuery.php
@@ -1,274 +1,242 @@
<?php
final class PhrictionDocumentQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
private $ids;
private $phids;
private $slugs;
private $needContent;
private $status = 'status-any';
const STATUS_ANY = 'status-any';
const STATUS_OPEN = 'status-open';
const STATUS_NONSTUB = 'status-nonstub';
private $order = 'order-created';
const ORDER_CREATED = 'order-created';
const ORDER_UPDATED = 'order-updated';
public function withIDs(array $ids) {
$this->ids = $ids;
return $this;
}
public function withPHIDs(array $phids) {
$this->phids = $phids;
return $this;
}
public function withSlugs(array $slugs) {
$this->slugs = $slugs;
return $this;
}
public function withStatus($status) {
$this->status = $status;
return $this;
}
public function needContent($need_content) {
$this->needContent = $need_content;
return $this;
}
public function setOrder($order) {
$this->order = $order;
return $this;
}
protected function loadPage() {
$table = new PhrictionDocument();
$conn_r = $table->establishConnection('r');
$rows = queryfx_all(
$conn_r,
'SELECT * FROM %T %Q %Q %Q',
$table->getTableName(),
$this->buildWhereClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
$documents = $table->loadAllFromArray($rows);
if ($documents) {
$ancestor_slugs = array();
foreach ($documents as $key => $document) {
$document_slug = $document->getSlug();
foreach (PhabricatorSlug::getAncestry($document_slug) as $ancestor) {
$ancestor_slugs[$ancestor][] = $key;
}
}
if ($ancestor_slugs) {
$ancestors = queryfx_all(
$conn_r,
'SELECT * FROM %T WHERE slug IN (%Ls)',
$document->getTableName(),
array_keys($ancestor_slugs));
$ancestors = $table->loadAllFromArray($ancestors);
$ancestors = mpull($ancestors, null, 'getSlug');
foreach ($ancestor_slugs as $ancestor_slug => $document_keys) {
$ancestor = idx($ancestors, $ancestor_slug);
foreach ($document_keys as $document_key) {
$documents[$document_key]->attachAncestor(
$ancestor_slug,
$ancestor);
}
}
}
}
return $documents;
}
protected function willFilterPage(array $documents) {
// 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
// not visible.
$document_map = array();
foreach ($documents as $document) {
$document_map[$document->getSlug()] = $document;
foreach ($document->getAncestors() as $key => $ancestor) {
if ($ancestor) {
$document_map[$key] = $ancestor;
}
}
}
$filtered_map = $this->applyPolicyFilter(
$document_map,
array(PhabricatorPolicyCapability::CAN_VIEW));
// Filter all of the documents where a parent is not visible.
foreach ($documents as $document_key => $document) {
// If the document itself is not visible, filter it.
if (!isset($filtered_map[$document->getSlug()])) {
$this->didRejectResult($documents[$document_key]);
unset($documents[$document_key]);
continue;
}
// If an ancestor exists but is not visible, filter the document.
foreach ($document->getAncestors() as $ancestor_key => $ancestor) {
if (!$ancestor) {
continue;
}
if (!isset($filtered_map[$ancestor_key])) {
$this->didRejectResult($documents[$document_key]);
unset($documents[$document_key]);
break;
}
}
}
if (!$documents) {
return $documents;
}
if ($this->needContent) {
$contents = id(new PhrictionContent())->loadAllWhere(
'id IN (%Ld)',
mpull($documents, 'getContentID'));
foreach ($documents as $key => $document) {
$content_id = $document->getContentID();
if (empty($contents[$content_id])) {
unset($documents[$key]);
continue;
}
$document->attachContent($contents[$content_id]);
}
}
- foreach ($documents as $document) {
- $document->attachProject(null);
- }
-
- $project_slugs = array();
- foreach ($documents as $key => $document) {
- $slug = $document->getSlug();
- if (!PhrictionDocument::isProjectSlug($slug)) {
- continue;
- }
- $project_slugs[$key] = PhrictionDocument::getProjectSlugIdentifier($slug);
- }
-
- if ($project_slugs) {
- $projects = id(new PhabricatorProjectQuery())
- ->setViewer($this->getViewer())
- ->withPhrictionSlugs($project_slugs)
- ->execute();
- $projects = mpull($projects, null, 'getPhrictionSlug');
- foreach ($documents as $key => $document) {
- $slug = idx($project_slugs, $key);
- if ($slug) {
- $project = idx($projects, $slug);
- if (!$project) {
- unset($documents[$key]);
- continue;
- }
- $document->attachProject($project);
- }
- }
- }
-
return $documents;
}
protected function buildWhereClause(AphrontDatabaseConnection $conn) {
$where = array();
if ($this->ids) {
$where[] = qsprintf(
$conn,
'id IN (%Ld)',
$this->ids);
}
if ($this->phids) {
$where[] = qsprintf(
$conn,
'phid IN (%Ls)',
$this->phids);
}
if ($this->slugs) {
$where[] = qsprintf(
$conn,
'slug IN (%Ls)',
$this->slugs);
}
switch ($this->status) {
case self::STATUS_OPEN:
$where[] = qsprintf(
$conn,
'status NOT IN (%Ld)',
array(
PhrictionDocumentStatus::STATUS_DELETED,
PhrictionDocumentStatus::STATUS_MOVED,
PhrictionDocumentStatus::STATUS_STUB,
));
break;
case self::STATUS_NONSTUB:
$where[] = qsprintf(
$conn,
'status NOT IN (%Ld)',
array(
PhrictionDocumentStatus::STATUS_MOVED,
PhrictionDocumentStatus::STATUS_STUB,
));
break;
case self::STATUS_ANY:
break;
default:
throw new Exception("Unknown status '{$this->status}'!");
}
$where[] = $this->buildPagingClause($conn);
return $this->formatWhereClause($where);
}
protected function getPagingColumn() {
switch ($this->order) {
case self::ORDER_CREATED:
return 'id';
case self::ORDER_UPDATED:
return 'contentID';
default:
throw new Exception("Unknown order '{$this->order}'!");
}
}
protected function getPagingValue($result) {
switch ($this->order) {
case self::ORDER_CREATED:
return $result->getID();
case self::ORDER_UPDATED:
return $result->getContentID();
default:
throw new Exception("Unknown order '{$this->order}'!");
}
}
public function getQueryApplicationClass() {
return 'PhabricatorPhrictionApplication';
}
}
diff --git a/src/applications/phriction/query/PhrictionSearchEngine.php b/src/applications/phriction/query/PhrictionSearchEngine.php
index 9e9a64d2d4..8b3f174f16 100644
--- a/src/applications/phriction/query/PhrictionSearchEngine.php
+++ b/src/applications/phriction/query/PhrictionSearchEngine.php
@@ -1,188 +1,180 @@
<?php
final class PhrictionSearchEngine
extends PhabricatorApplicationSearchEngine {
public function getResultTypeDescription() {
return pht('Wiki Documents');
}
public function buildSavedQueryFromRequest(AphrontRequest $request) {
$saved = new PhabricatorSavedQuery();
$saved->setParameter('status', $request->getArr('status'));
$saved->setParameter('order', $request->getArr('order'));
return $saved;
}
public function buildQueryFromSavedQuery(PhabricatorSavedQuery $saved) {
$query = id(new PhrictionDocumentQuery())
->needContent(true)
->withStatus(PhrictionDocumentQuery::STATUS_NONSTUB);
$status = $saved->getParameter('status');
$status = idx($this->getStatusValues(), $status);
if ($status) {
$query->withStatus($status);
}
$order = $saved->getParameter('order');
$order = idx($this->getOrderValues(), $order);
if ($order) {
$query->setOrder($order);
}
return $query;
}
public function buildSearchForm(
AphrontFormView $form,
PhabricatorSavedQuery $saved_query) {
$form
->appendChild(
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) {
return '/phriction/'.$path;
}
public function getBuiltinQueryNames() {
$names = array(
'active' => pht('Active'),
'updated' => pht('Updated'),
'all' => pht('All'),
);
return $names;
}
public function buildSavedQueryFromBuiltin($query_key) {
$query = $this->newSavedQuery();
$query->setQueryKey($query_key);
switch ($query_key) {
case 'active':
return $query->setParameter('status', 'active');
case 'all':
return $query;
case 'updated':
return $query->setParameter('order', 'updated');
}
return parent::buildSavedQueryFromBuiltin($query_key);
}
private function getStatusOptions() {
return array(
'active' => pht('Show Active Documents'),
'all' => 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,
);
}
protected function getRequiredHandlePHIDsForResultList(
array $documents,
PhabricatorSavedQuery $query) {
$phids = array();
foreach ($documents as $document) {
$content = $document->getContent();
- if ($document->hasProject()) {
- $phids[] = $document->getProject()->getPHID();
- }
$phids[] = $content->getAuthorPHID();
}
return $phids;
}
protected function renderResultList(
array $documents,
PhabricatorSavedQuery $query,
array $handles) {
assert_instances_of($documents, 'PhrictionDocument');
$viewer = $this->requireViewer();
$list = new PHUIObjectItemListView();
$list->setUser($viewer);
foreach ($documents as $document) {
$content = $document->getContent();
$slug = $document->getSlug();
$author_phid = $content->getAuthorPHID();
$slug_uri = PhrictionDocument::getSlugURI($slug);
$byline = pht(
'Edited by %s',
$handles[$author_phid]->renderLink());
$updated = phabricator_datetime(
$content->getDateCreated(),
$viewer);
$item = id(new PHUIObjectItemView())
->setHeader($content->getTitle())
->setHref($slug_uri)
->addByline($byline)
->addIcon('none', $updated);
- if ($document->hasProject()) {
- $item->addAttribute(
- $handles[$document->getProject()->getPHID()]->renderLink());
- }
-
$item->addAttribute($slug_uri);
switch ($document->getStatus()) {
case PhrictionDocumentStatus::STATUS_DELETED:
$item->setDisabled(true);
$item->addIcon('delete', pht('Deleted'));
break;
case PhrictionDocumentStatus::STATUS_MOVED:
$item->setDisabled(true);
$item->addIcon('arrow-right', pht('Moved Away'));
break;
}
$list->addItem($item);
}
return $list;
}
}
diff --git a/src/applications/phriction/storage/PhrictionDocument.php b/src/applications/phriction/storage/PhrictionDocument.php
index 070b3106ce..40606fc768 100644
--- a/src/applications/phriction/storage/PhrictionDocument.php
+++ b/src/applications/phriction/storage/PhrictionDocument.php
@@ -1,266 +1,252 @@
<?php
final class PhrictionDocument extends PhrictionDAO
implements
PhabricatorPolicyInterface,
PhabricatorSubscribableInterface,
PhabricatorFlaggableInterface,
PhabricatorTokenReceiverInterface,
PhabricatorDestructibleInterface {
protected $slug;
protected $depth;
protected $contentID;
protected $status;
protected $mailKey;
protected $viewPolicy;
protected $editPolicy;
private $contentObject = self::ATTACHABLE;
private $ancestors = array();
- private $project = self::ATTACHABLE;
public function getConfiguration() {
return array(
self::CONFIG_AUX_PHID => true,
self::CONFIG_TIMESTAMPS => false,
self::CONFIG_COLUMN_SCHEMA => array(
'slug' => 'sort128',
'depth' => 'uint32',
'contentID' => 'id?',
'status' => 'uint32',
'mailKey' => 'bytes20',
),
self::CONFIG_KEY_SCHEMA => array(
'key_phid' => null,
'phid' => array(
'columns' => array('phid'),
'unique' => true,
),
'slug' => array(
'columns' => array('slug'),
'unique' => true,
),
'depth' => array(
'columns' => array('depth', 'slug'),
'unique' => true,
),
),
) + parent::getConfiguration();
}
public function generatePHID() {
return PhabricatorPHID::generateNewPHID(
PhrictionDocumentPHIDType::TYPECONST);
}
public static function initializeNewDocument(PhabricatorUser $actor, $slug) {
$document = new PhrictionDocument();
$document->setSlug($slug);
$content = new PhrictionContent();
$content->setSlug($slug);
$default_title = PhabricatorSlug::getDefaultTitle($slug);
$content->setTitle($default_title);
$document->attachContent($content);
$parent_doc = null;
$ancestral_slugs = PhabricatorSlug::getAncestry($slug);
if ($ancestral_slugs) {
$parent = end($ancestral_slugs);
$parent_doc = id(new PhrictionDocumentQuery())
->setViewer($actor)
->withSlugs(array($parent))
->executeOne();
}
if ($parent_doc) {
$document->setViewPolicy($parent_doc->getViewPolicy());
$document->setEditPolicy($parent_doc->getEditPolicy());
} else {
$default_view_policy = PhabricatorPolicies::getMostOpenPolicy();
$document->setViewPolicy($default_view_policy);
$document->setEditPolicy(PhabricatorPolicies::POLICY_USER);
}
return $document;
}
public function save() {
if (!$this->getMailKey()) {
$this->setMailKey(Filesystem::readRandomCharacters(20));
}
return parent::save();
}
public static function getSlugURI($slug, $type = 'document') {
static $types = array(
'document' => '/w/',
'history' => '/phriction/history/',
);
if (empty($types[$type])) {
throw new Exception("Unknown URI type '{$type}'!");
}
$prefix = $types[$type];
if ($slug == '/') {
return $prefix;
} else {
// NOTE: The effect here is to escape non-latin characters, since modern
// browsers deal with escaped UTF8 characters in a reasonable way (showing
// the user a readable URI) but older programs may not.
$slug = phutil_escape_uri($slug);
return $prefix.$slug;
}
}
public function setSlug($slug) {
$this->slug = PhabricatorSlug::normalize($slug);
$this->depth = PhabricatorSlug::getDepth($slug);
return $this;
}
public function attachContent(PhrictionContent $content) {
$this->contentObject = $content;
return $this;
}
public function getContent() {
return $this->assertAttached($this->contentObject);
}
- public function getProject() {
- return $this->assertAttached($this->project);
- }
-
- public function attachProject(PhabricatorProject $project = null) {
- $this->project = $project;
- return $this;
- }
-
- public function hasProject() {
- return (bool)$this->getProject();
- }
-
public function getAncestors() {
return $this->ancestors;
}
public function getAncestor($slug) {
return $this->assertAttachedKey($this->ancestors, $slug);
}
public function attachAncestor($slug, $ancestor) {
$this->ancestors[$slug] = $ancestor;
return $this;
}
public static function isProjectSlug($slug) {
$slug = PhabricatorSlug::normalize($slug);
$prefix = 'projects/';
if ($slug == $prefix) {
// The 'projects/' document is not itself a project slug.
return false;
}
return !strncmp($slug, $prefix, strlen($prefix));
}
public static function getProjectSlugIdentifier($slug) {
if (!self::isProjectSlug($slug)) {
throw new Exception("Slug '{$slug}' is not a project slug!");
}
$slug = PhabricatorSlug::normalize($slug);
$parts = explode('/', $slug);
return $parts[1].'/';
}
/* -( PhabricatorPolicyInterface )----------------------------------------- */
public function getCapabilities() {
return array(
PhabricatorPolicyCapability::CAN_VIEW,
PhabricatorPolicyCapability::CAN_EDIT,
);
}
public function getPolicy($capability) {
switch ($capability) {
case PhabricatorPolicyCapability::CAN_VIEW:
return $this->getViewPolicy();
case PhabricatorPolicyCapability::CAN_EDIT:
return $this->getEditPolicy();
}
}
public function hasAutomaticCapability($capability, PhabricatorUser $user) {
return false;
}
public function describeAutomaticCapability($capability) {
switch ($capability) {
case PhabricatorPolicyCapability::CAN_VIEW:
return pht(
'To view a wiki document, you must also be able to view all '.
'of its parents.');
case PhabricatorPolicyCapability::CAN_EDIT:
return pht(
'To edit a wiki document, you must also be able to view all '.
'of its parents.');
}
return null;
}
/* -( PhabricatorSubscribableInterface )----------------------------------- */
public function isAutomaticallySubscribed($phid) {
return false;
}
public function shouldShowSubscribersProperty() {
return true;
}
public function shouldAllowSubscription($phid) {
return true;
}
/* -( PhabricatorTokenReceiverInterface )---------------------------------- */
public function getUsersToNotifyOfTokenGiven() {
return PhabricatorSubscribersQuery::loadSubscribersForPHID($this->phid);
}
/* -( PhabricatorDestructibleInterface )----------------------------------- */
public function destroyObjectPermanently(
PhabricatorDestructionEngine $engine) {
$this->openTransaction();
$this->delete();
$contents = id(new PhrictionContent())->loadAllWhere(
'documentID = %d',
$this->getID());
foreach ($contents as $content) {
$content->delete();
}
$this->saveTransaction();
}
}

File Metadata

Mime Type
text/x-diff
Expires
Sun, Jan 19, 18:56 (1 w, 4 d ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1127611
Default Alt Text
(20 KB)

Event Timeline