Page MenuHomestyx hydra

No OneTemporary

This file is larger than 256 KB, so syntax highlighting was skipped.
diff --git a/src/applications/auth/query/PhabricatorExternalAccountQuery.php b/src/applications/auth/query/PhabricatorExternalAccountQuery.php
index 3d1bff2888..9bb611015d 100644
--- a/src/applications/auth/query/PhabricatorExternalAccountQuery.php
+++ b/src/applications/auth/query/PhabricatorExternalAccountQuery.php
@@ -1,211 +1,211 @@
<?php
/**
* NOTE: When loading ExternalAccounts for use in an authentication context
* (that is, you're going to act as the account or link identities or anything
* like that) you should require CAN_EDIT capability even if you aren't actually
* editing the ExternalAccount.
*
* ExternalAccounts have a permissive CAN_VIEW policy (like users) because they
* interact directly with objects and can leave comments, sign documents, etc.
* However, CAN_EDIT is restricted to users who own the accounts.
*/
final class PhabricatorExternalAccountQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
private $ids;
private $phids;
private $accountTypes;
private $accountDomains;
private $accountIDs;
private $userPHIDs;
private $needImages;
private $accountSecrets;
public function withUserPHIDs(array $user_phids) {
$this->userPHIDs = $user_phids;
return $this;
}
public function withAccountIDs(array $account_ids) {
$this->accountIDs = $account_ids;
return $this;
}
public function withAccountDomains(array $account_domains) {
$this->accountDomains = $account_domains;
return $this;
}
public function withAccountTypes(array $account_types) {
$this->accountTypes = $account_types;
return $this;
}
public function withPHIDs(array $phids) {
$this->phids = $phids;
return $this;
}
public function withIDs($ids) {
$this->ids = $ids;
return $this;
}
public function withAccountSecrets(array $secrets) {
$this->accountSecrets = $secrets;
return $this;
}
public function needImages($need) {
$this->needImages = $need;
return $this;
}
- public function loadPage() {
+ protected function loadPage() {
$table = new PhabricatorExternalAccount();
$conn_r = $table->establishConnection('r');
$data = queryfx_all(
$conn_r,
'SELECT * FROM %T %Q %Q %Q',
$table->getTableName(),
$this->buildWhereClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
return $table->loadAllFromArray($data);
}
- public function willFilterPage(array $accounts) {
+ protected function willFilterPage(array $accounts) {
if ($this->needImages) {
$file_phids = mpull($accounts, 'getProfileImagePHID');
$file_phids = array_filter($file_phids);
if ($file_phids) {
// NOTE: We use the omnipotent viewer here because these files are
// usually created during registration and can't be associated with
// the correct policies, since the relevant user account does not exist
// yet. In effect, if you can see an ExternalAccount, you can see its
// profile image.
$files = id(new PhabricatorFileQuery())
->setViewer(PhabricatorUser::getOmnipotentUser())
->withPHIDs($file_phids)
->execute();
$files = mpull($files, null, 'getPHID');
} else {
$files = array();
}
$default_file = null;
foreach ($accounts as $account) {
$image_phid = $account->getProfileImagePHID();
if ($image_phid && isset($files[$image_phid])) {
$account->attachProfileImageFile($files[$image_phid]);
} else {
if ($default_file === null) {
$default_file = PhabricatorFile::loadBuiltin(
$this->getViewer(),
'profile.png');
}
$account->attachProfileImageFile($default_file);
}
}
}
return $accounts;
}
protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();
$where[] = $this->buildPagingClause($conn_r);
if ($this->ids) {
$where[] = qsprintf(
$conn_r,
'id IN (%Ld)',
$this->ids);
}
if ($this->phids) {
$where[] = qsprintf(
$conn_r,
'phid IN (%Ls)',
$this->phids);
}
if ($this->accountTypes) {
$where[] = qsprintf(
$conn_r,
'accountType IN (%Ls)',
$this->accountTypes);
}
if ($this->accountDomains) {
$where[] = qsprintf(
$conn_r,
'accountDomain IN (%Ls)',
$this->accountDomains);
}
if ($this->accountIDs) {
$where[] = qsprintf(
$conn_r,
'accountID IN (%Ls)',
$this->accountIDs);
}
if ($this->userPHIDs) {
$where[] = qsprintf(
$conn_r,
'userPHID IN (%Ls)',
$this->userPHIDs);
}
if ($this->accountSecrets) {
$where[] = qsprintf(
$conn_r,
'accountSecret IN (%Ls)',
$this->accountSecrets);
}
return $this->formatWhereClause($where);
}
public function getQueryApplicationClass() {
return 'PhabricatorPeopleApplication';
}
/**
* Attempts to find an external account and if none exists creates a new
* external account with a shiny new ID and PHID.
*
* NOTE: This function assumes the first item in various query parameters is
* the correct value to use in creating a new external account.
*/
public function loadOneOrCreate() {
$account = $this->executeOne();
if (!$account) {
$account = new PhabricatorExternalAccount();
if ($this->accountIDs) {
$account->setAccountID(reset($this->accountIDs));
}
if ($this->accountTypes) {
$account->setAccountType(reset($this->accountTypes));
}
if ($this->accountDomains) {
$account->setAccountDomain(reset($this->accountDomains));
}
if ($this->accountSecrets) {
$account->setAccountSecret(reset($this->accountSecrets));
}
if ($this->userPHIDs) {
$account->setUserPHID(reset($this->userPHIDs));
}
$account->save();
}
return $account;
}
}
diff --git a/src/applications/chatlog/query/PhabricatorChatLogQuery.php b/src/applications/chatlog/query/PhabricatorChatLogQuery.php
index a077c0c69e..cb7fe53128 100644
--- a/src/applications/chatlog/query/PhabricatorChatLogQuery.php
+++ b/src/applications/chatlog/query/PhabricatorChatLogQuery.php
@@ -1,84 +1,84 @@
<?php
final class PhabricatorChatLogQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
private $channelIDs;
private $maximumEpoch;
public function withChannelIDs(array $channel_ids) {
$this->channelIDs = $channel_ids;
return $this;
}
public function withMaximumEpoch($epoch) {
$this->maximumEpoch = $epoch;
return $this;
}
protected function loadPage() {
$table = new PhabricatorChatLogEvent();
$conn_r = $table->establishConnection('r');
$data = queryfx_all(
$conn_r,
'SELECT * FROM %T e %Q %Q %Q',
$table->getTableName(),
$this->buildWhereClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
$logs = $table->loadAllFromArray($data);
return $logs;
}
- public function willFilterPage(array $events) {
+ protected function willFilterPage(array $events) {
$channel_ids = mpull($events, 'getChannelID', 'getChannelID');
$channels = id(new PhabricatorChatLogChannelQuery())
->setViewer($this->getViewer())
->withIDs($channel_ids)
->execute();
$channels = mpull($channels, null, 'getID');
foreach ($events as $key => $event) {
$channel = idx($channels, $event->getChannelID());
if (!$channel) {
unset($events[$key]);
continue;
}
$event->attachChannel($channel);
}
return $events;
}
private function buildWhereClause($conn_r) {
$where = array();
$where[] = $this->buildPagingClause($conn_r);
if ($this->maximumEpoch) {
$where[] = qsprintf(
$conn_r,
'epoch <= %d',
$this->maximumEpoch);
}
if ($this->channelIDs) {
$where[] = qsprintf(
$conn_r,
'channelID IN (%Ld)',
$this->channelIDs);
}
return $this->formatWhereClause($where);
}
public function getQueryApplicationClass() {
return 'PhabricatorChatLogApplication';
}
}
diff --git a/src/applications/conduit/query/PhabricatorConduitLogQuery.php b/src/applications/conduit/query/PhabricatorConduitLogQuery.php
index b98f5585fc..56934caf45 100644
--- a/src/applications/conduit/query/PhabricatorConduitLogQuery.php
+++ b/src/applications/conduit/query/PhabricatorConduitLogQuery.php
@@ -1,46 +1,46 @@
<?php
final class PhabricatorConduitLogQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
private $methods;
public function withMethods(array $methods) {
$this->methods = $methods;
return $this;
}
- public function loadPage() {
+ protected function loadPage() {
$table = new PhabricatorConduitMethodCallLog();
$conn_r = $table->establishConnection('r');
$data = queryfx_all(
$conn_r,
'SELECT * FROM %T %Q %Q %Q',
$table->getTableName(),
$this->buildWhereClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
return $table->loadAllFromArray($data);;
}
private function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();
if ($this->methods) {
$where[] = qsprintf(
$conn_r,
'method IN (%Ls)',
$this->methods);
}
$where[] = $this->buildPagingClause($conn_r);
return $this->formatWhereClause($where);
}
public function getQueryApplicationClass() {
return 'PhabricatorConduitApplication';
}
}
diff --git a/src/applications/conduit/query/PhabricatorConduitMethodQuery.php b/src/applications/conduit/query/PhabricatorConduitMethodQuery.php
index d427344f1e..fa9592f8e8 100644
--- a/src/applications/conduit/query/PhabricatorConduitMethodQuery.php
+++ b/src/applications/conduit/query/PhabricatorConduitMethodQuery.php
@@ -1,126 +1,126 @@
<?php
final class PhabricatorConduitMethodQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
private $isDeprecated;
private $isStable;
private $isUnstable;
private $applicationNames;
private $nameContains;
private $methods;
public function withMethods(array $methods) {
$this->methods = $methods;
return $this;
}
public function withNameContains($name_contains) {
$this->nameContains = $name_contains;
return $this;
}
public function withApplicationNames(array $application_names) {
$this->applicationNames = $application_names;
return $this;
}
public function withIsStable($is_stable) {
$this->isStable = $is_stable;
return $this;
}
public function withIsUnstable($is_unstable) {
$this->isUnstable = $is_unstable;
return $this;
}
public function withIsDeprecated($is_deprecated) {
$this->isDeprecated = $is_deprecated;
return $this;
}
- public function loadPage() {
+ protected function loadPage() {
$methods = $this->getAllMethods();
$methods = $this->filterMethods($methods);
return $methods;
}
private function getAllMethods() {
static $methods;
if ($methods === null) {
$methods = id(new PhutilSymbolLoader())
->setAncestorClass('ConduitAPIMethod')
->loadObjects();
$methods = msort($methods, 'getSortOrder');
}
return $methods;
}
private function filterMethods(array $methods) {
foreach ($methods as $key => $method) {
$application = $method->getApplication();
if (!$application) {
continue;
}
if (!$application->isInstalled()) {
unset($methods[$key]);
}
}
$status = array(
ConduitAPIMethod::METHOD_STATUS_STABLE => $this->isStable,
ConduitAPIMethod::METHOD_STATUS_DEPRECATED => $this->isDeprecated,
ConduitAPIMethod::METHOD_STATUS_UNSTABLE => $this->isUnstable,
);
// Only apply status filters if any of them are set.
if (array_filter($status)) {
foreach ($methods as $key => $method) {
$keep = idx($status, $method->getMethodStatus());
if (!$keep) {
unset($methods[$key]);
}
}
}
if ($this->applicationNames) {
$map = array_fuse($this->applicationNames);
foreach ($methods as $key => $method) {
$needle = $method->getApplicationName();
$needle = phutil_utf8_strtolower($needle);
if (empty($map[$needle])) {
unset($methods[$key]);
}
}
}
if ($this->nameContains) {
$needle = phutil_utf8_strtolower($this->nameContains);
foreach ($methods as $key => $method) {
$haystack = $method->getAPIMethodName();
$haystack = phutil_utf8_strtolower($haystack);
if (strpos($haystack, $needle) === false) {
unset($methods[$key]);
}
}
}
if ($this->methods) {
$map = array_fuse($this->methods);
foreach ($methods as $key => $method) {
$needle = $method->getAPIMethodName();
if (empty($map[$needle])) {
unset($methods[$key]);
}
}
}
return $methods;
}
public function getQueryApplicationClass() {
return 'PhabricatorConduitApplication';
}
}
diff --git a/src/applications/conduit/query/PhabricatorConduitTokenQuery.php b/src/applications/conduit/query/PhabricatorConduitTokenQuery.php
index 38a258c4ed..563e437a4a 100644
--- a/src/applications/conduit/query/PhabricatorConduitTokenQuery.php
+++ b/src/applications/conduit/query/PhabricatorConduitTokenQuery.php
@@ -1,128 +1,128 @@
<?php
final class PhabricatorConduitTokenQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
private $ids;
private $objectPHIDs;
private $expired;
private $tokens;
private $tokenTypes;
public function withExpired($expired) {
$this->expired = $expired;
return $this;
}
public function withIDs(array $ids) {
$this->ids = $ids;
return $this;
}
public function withObjectPHIDs(array $phids) {
$this->objectPHIDs = $phids;
return $this;
}
public function withTokens(array $tokens) {
$this->tokens = $tokens;
return $this;
}
public function withTokenTypes(array $types) {
$this->tokenTypes = $types;
return $this;
}
- public function loadPage() {
+ protected function loadPage() {
$table = new PhabricatorConduitToken();
$conn_r = $table->establishConnection('r');
$data = queryfx_all(
$conn_r,
'SELECT * FROM %T %Q %Q %Q',
$table->getTableName(),
$this->buildWhereClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
return $table->loadAllFromArray($data);;
}
private function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();
if ($this->ids !== null) {
$where[] = qsprintf(
$conn_r,
'id IN (%Ld)',
$this->ids);
}
if ($this->objectPHIDs !== null) {
$where[] = qsprintf(
$conn_r,
'objectPHID IN (%Ls)',
$this->objectPHIDs);
}
if ($this->tokens !== null) {
$where[] = qsprintf(
$conn_r,
'token IN (%Ls)',
$this->tokens);
}
if ($this->tokenTypes !== null) {
$where[] = qsprintf(
$conn_r,
'tokenType IN (%Ls)',
$this->tokenTypes);
}
if ($this->expired !== null) {
if ($this->expired) {
$where[] = qsprintf(
$conn_r,
'expires <= %d',
PhabricatorTime::getNow());
} else {
$where[] = qsprintf(
$conn_r,
'expires IS NULL OR expires > %d',
PhabricatorTime::getNow());
}
}
$where[] = $this->buildPagingClause($conn_r);
return $this->formatWhereClause($where);
}
protected function willFilterPage(array $tokens) {
$object_phids = mpull($tokens, 'getObjectPHID');
$objects = id(new PhabricatorObjectQuery())
->setViewer($this->getViewer())
->setParentQuery($this)
->withPHIDs($object_phids)
->execute();
$objects = mpull($objects, null, 'getPHID');
foreach ($tokens as $key => $token) {
$object = idx($objects, $token->getObjectPHID(), null);
if (!$object) {
$this->didRejectResult($token);
unset($tokens[$key]);
continue;
}
$token->attachObject($object);
}
return $tokens;
}
public function getQueryApplicationClass() {
return 'PhabricatorConduitApplication';
}
}
diff --git a/src/applications/config/query/PhabricatorConfigEntryQuery.php b/src/applications/config/query/PhabricatorConfigEntryQuery.php
index 9d140b047f..01982ca7d0 100644
--- a/src/applications/config/query/PhabricatorConfigEntryQuery.php
+++ b/src/applications/config/query/PhabricatorConfigEntryQuery.php
@@ -1,60 +1,60 @@
<?php
final class PhabricatorConfigEntryQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
private $phids;
private $ids;
public function withIDs($ids) {
$this->ids = $ids;
return $this;
}
public function withPHIDs($phids) {
$this->phids = $phids;
return $this;
}
- public function loadPage() {
+ protected function loadPage() {
$table = new PhabricatorConfigEntry();
$conn_r = $table->establishConnection('r');
$data = queryfx_all(
$conn_r,
'SELECT * FROM %T %Q %Q %Q',
$table->getTableName(),
$this->buildWhereClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
return $table->loadAllFromArray($data);
}
private function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();
if ($this->ids) {
$where[] = qsprintf(
$conn_r,
'id IN (%Ld)',
$this->ids);
}
if ($this->phids) {
$where[] = qsprintf(
$conn_r,
'phid IN (%Ls)',
$this->phids);
}
$where[] = $this->buildPagingClause($conn_r);
return $this->formatWhereClause($where);
}
public function getQueryApplicationClass() {
return 'PhabricatorConfigApplication';
}
}
diff --git a/src/applications/daemon/query/PhabricatorDaemonLogQuery.php b/src/applications/daemon/query/PhabricatorDaemonLogQuery.php
index 6da5155193..9994c21a71 100644
--- a/src/applications/daemon/query/PhabricatorDaemonLogQuery.php
+++ b/src/applications/daemon/query/PhabricatorDaemonLogQuery.php
@@ -1,176 +1,176 @@
<?php
final class PhabricatorDaemonLogQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
const STATUS_ALL = 'status-all';
const STATUS_ALIVE = 'status-alive';
private $ids;
private $notIDs;
private $status = self::STATUS_ALL;
private $daemonClasses;
private $allowStatusWrites;
public static function getTimeUntilUnknown() {
return 3 * PhutilDaemonOverseer::HEARTBEAT_WAIT;
}
public static function getTimeUntilDead() {
return 30 * PhutilDaemonOverseer::HEARTBEAT_WAIT;
}
public function withIDs(array $ids) {
$this->ids = $ids;
return $this;
}
public function withoutIDs(array $ids) {
$this->notIDs = $ids;
return $this;
}
public function withStatus($status) {
$this->status = $status;
return $this;
}
public function withDaemonClasses(array $classes) {
$this->daemonClasses = $classes;
return $this;
}
public function setAllowStatusWrites($allow) {
$this->allowStatusWrites = $allow;
return $this;
}
- public function loadPage() {
+ protected function loadPage() {
$table = new PhabricatorDaemonLog();
$conn_r = $table->establishConnection('r');
$data = queryfx_all(
$conn_r,
'SELECT * FROM %T %Q %Q %Q',
$table->getTableName(),
$this->buildWhereClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
return $table->loadAllFromArray($data);
}
- public function willFilterPage(array $daemons) {
+ protected function willFilterPage(array $daemons) {
$unknown_delay = PhabricatorDaemonLogQuery::getTimeUntilUnknown();
$dead_delay = PhabricatorDaemonLogQuery::getTimeUntilDead();
$status_running = PhabricatorDaemonLog::STATUS_RUNNING;
$status_unknown = PhabricatorDaemonLog::STATUS_UNKNOWN;
$status_wait = PhabricatorDaemonLog::STATUS_WAIT;
$status_exiting = PhabricatorDaemonLog::STATUS_EXITING;
$status_exited = PhabricatorDaemonLog::STATUS_EXITED;
$status_dead = PhabricatorDaemonLog::STATUS_DEAD;
$filter = array_fuse($this->getStatusConstants());
foreach ($daemons as $key => $daemon) {
$status = $daemon->getStatus();
$seen = $daemon->getDateModified();
$is_running = ($status == $status_running) ||
($status == $status_wait) ||
($status == $status_exiting);
// If we haven't seen the daemon recently, downgrade its status to
// unknown.
$unknown_time = ($seen + $unknown_delay);
if ($is_running && ($unknown_time < time())) {
$status = $status_unknown;
}
// If the daemon hasn't been seen in quite a while, assume it is dead.
$dead_time = ($seen + $dead_delay);
if (($status == $status_unknown) && ($dead_time < time())) {
$status = $status_dead;
}
// If we changed the daemon's status, adjust it.
if ($status != $daemon->getStatus()) {
$daemon->setStatus($status);
// ...and write it, if we're in a context where that's reasonable.
if ($this->allowStatusWrites) {
$guard = AphrontWriteGuard::beginScopedUnguardedWrites();
$daemon->save();
unset($guard);
}
}
// If the daemon no longer matches the filter, get rid of it.
if ($filter) {
if (empty($filter[$daemon->getStatus()])) {
unset($daemons[$key]);
}
}
}
return $daemons;
}
private function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();
if ($this->ids) {
$where[] = qsprintf(
$conn_r,
'id IN (%Ld)',
$this->ids);
}
if ($this->notIDs) {
$where[] = qsprintf(
$conn_r,
'id NOT IN (%Ld)',
$this->notIDs);
}
if ($this->getStatusConstants()) {
$where[] = qsprintf(
$conn_r,
'status IN (%Ls)',
$this->getStatusConstants());
}
if ($this->daemonClasses) {
$where[] = qsprintf(
$conn_r,
'daemon IN (%Ls)',
$this->daemonClasses);
}
$where[] = $this->buildPagingClause($conn_r);
return $this->formatWhereClause($where);
}
private function getStatusConstants() {
$status = $this->status;
switch ($status) {
case self::STATUS_ALL:
return array();
case self::STATUS_ALIVE:
return array(
PhabricatorDaemonLog::STATUS_UNKNOWN,
PhabricatorDaemonLog::STATUS_RUNNING,
PhabricatorDaemonLog::STATUS_WAIT,
PhabricatorDaemonLog::STATUS_EXITING,
);
default:
throw new Exception("Unknown status '{$status}'!");
}
}
public function getQueryApplicationClass() {
return 'PhabricatorDaemonsApplication';
}
}
diff --git a/src/applications/differential/query/DifferentialChangesetQuery.php b/src/applications/differential/query/DifferentialChangesetQuery.php
index 57a5464c5c..9f19dae847 100644
--- a/src/applications/differential/query/DifferentialChangesetQuery.php
+++ b/src/applications/differential/query/DifferentialChangesetQuery.php
@@ -1,157 +1,157 @@
<?php
final class DifferentialChangesetQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
private $ids;
private $diffs;
private $needAttachToDiffs;
private $needHunks;
public function withIDs(array $ids) {
$this->ids = $ids;
return $this;
}
public function withDiffs(array $diffs) {
assert_instances_of($diffs, 'DifferentialDiff');
$this->diffs = $diffs;
return $this;
}
public function needAttachToDiffs($attach) {
$this->needAttachToDiffs = $attach;
return $this;
}
public function needHunks($need) {
$this->needHunks = $need;
return $this;
}
- public function willExecute() {
+ protected function willExecute() {
// If we fail to load any changesets (which is possible in the case of an
// empty commit) we'll never call didFilterPage(). Attach empty changeset
// lists now so that we end up with the right result.
if ($this->needAttachToDiffs) {
foreach ($this->diffs as $diff) {
$diff->attachChangesets(array());
}
}
}
- public function loadPage() {
+ protected function loadPage() {
$table = new DifferentialChangeset();
$conn_r = $table->establishConnection('r');
$data = queryfx_all(
$conn_r,
'SELECT * FROM %T %Q %Q %Q',
$table->getTableName(),
$this->buildWhereClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
return $table->loadAllFromArray($data);
}
- public function willFilterPage(array $changesets) {
+ protected function willFilterPage(array $changesets) {
// First, attach all the diffs we already have. We can just do this
// directly without worrying about querying for them. When we don't have
// a diff, record that we need to load it.
if ($this->diffs) {
$have_diffs = mpull($this->diffs, null, 'getID');
} else {
$have_diffs = array();
}
$must_load = array();
foreach ($changesets as $key => $changeset) {
$diff_id = $changeset->getDiffID();
if (isset($have_diffs[$diff_id])) {
$changeset->attachDiff($have_diffs[$diff_id]);
} else {
$must_load[$key] = $changeset;
}
}
// Load all the diffs we don't have.
$need_diff_ids = mpull($must_load, 'getDiffID');
$more_diffs = array();
if ($need_diff_ids) {
$more_diffs = id(new DifferentialDiffQuery())
->setViewer($this->getViewer())
->setParentQuery($this)
->withIDs($need_diff_ids)
->execute();
$more_diffs = mpull($more_diffs, null, 'getID');
}
// Attach the diffs we loaded.
foreach ($must_load as $key => $changeset) {
$diff_id = $changeset->getDiffID();
if (isset($more_diffs[$diff_id])) {
$changeset->attachDiff($more_diffs[$diff_id]);
} else {
// We didn't have the diff, and could not load it (it does not exist,
// or we can't see it), so filter this result out.
unset($changesets[$key]);
}
}
return $changesets;
}
- public function didFilterPage(array $changesets) {
+ protected function didFilterPage(array $changesets) {
if ($this->needAttachToDiffs) {
$changeset_groups = mgroup($changesets, 'getDiffID');
foreach ($this->diffs as $diff) {
$diff_changesets = idx($changeset_groups, $diff->getID(), array());
$diff->attachChangesets($diff_changesets);
}
}
if ($this->needHunks) {
id(new DifferentialHunkQuery())
->setViewer($this->getViewer())
->setParentQuery($this)
->withChangesets($changesets)
->needAttachToChangesets(true)
->execute();
}
return $changesets;
}
private function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();
if ($this->diffs !== null) {
$where[] = qsprintf(
$conn_r,
'diffID IN (%Ld)',
mpull($this->diffs, 'getID'));
}
if ($this->ids !== null) {
$where[] = qsprintf(
$conn_r,
'id IN (%Ld)',
$this->ids);
}
$where[] = $this->buildPagingClause($conn_r);
return $this->formatWhereClause($where);
}
public function getQueryApplicationClass() {
return 'PhabricatorDifferentialApplication';
}
protected function getReversePaging() {
return true;
}
}
diff --git a/src/applications/differential/query/DifferentialDiffQuery.php b/src/applications/differential/query/DifferentialDiffQuery.php
index 4fc3ffcdfe..3d58e12f8a 100644
--- a/src/applications/differential/query/DifferentialDiffQuery.php
+++ b/src/applications/differential/query/DifferentialDiffQuery.php
@@ -1,156 +1,156 @@
<?php
final class DifferentialDiffQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
private $ids;
private $phids;
private $revisionIDs;
private $needChangesets = false;
private $needArcanistProjects = false;
public function withIDs(array $ids) {
$this->ids = $ids;
return $this;
}
public function withPHIDs(array $phids) {
$this->phids = $phids;
return $this;
}
public function withRevisionIDs(array $revision_ids) {
$this->revisionIDs = $revision_ids;
return $this;
}
public function needChangesets($bool) {
$this->needChangesets = $bool;
return $this;
}
public function needArcanistProjects($bool) {
$this->needArcanistProjects = $bool;
return $this;
}
- public function loadPage() {
+ protected function loadPage() {
$table = new DifferentialDiff();
$conn_r = $table->establishConnection('r');
$data = queryfx_all(
$conn_r,
'SELECT * FROM %T %Q %Q %Q',
$table->getTableName(),
$this->buildWhereClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
return $table->loadAllFromArray($data);
}
- public function willFilterPage(array $diffs) {
+ protected function willFilterPage(array $diffs) {
$revision_ids = array_filter(mpull($diffs, 'getRevisionID'));
$revisions = array();
if ($revision_ids) {
$revisions = id(new DifferentialRevisionQuery())
->setViewer($this->getViewer())
->withIDs($revision_ids)
->execute();
}
foreach ($diffs as $key => $diff) {
if (!$diff->getRevisionID()) {
continue;
}
$revision = idx($revisions, $diff->getRevisionID());
if ($revision) {
$diff->attachRevision($revision);
continue;
}
unset($diffs[$key]);
}
if ($diffs && $this->needChangesets) {
$diffs = $this->loadChangesets($diffs);
}
if ($diffs && $this->needArcanistProjects) {
$diffs = $this->loadArcanistProjects($diffs);
}
return $diffs;
}
private function loadChangesets(array $diffs) {
id(new DifferentialChangesetQuery())
->setViewer($this->getViewer())
->setParentQuery($this)
->withDiffs($diffs)
->needAttachToDiffs(true)
->needHunks(true)
->execute();
return $diffs;
}
private function loadArcanistProjects(array $diffs) {
$phids = array_filter(mpull($diffs, 'getArcanistProjectPHID'));
$projects = array();
$project_map = array();
if ($phids) {
$projects = id(new PhabricatorRepositoryArcanistProject())
->loadAllWhere(
'phid IN (%Ls)',
$phids);
$project_map = mpull($projects, null, 'getPHID');
}
foreach ($diffs as $diff) {
$project = null;
if ($diff->getArcanistProjectPHID()) {
$project = idx($project_map, $diff->getArcanistProjectPHID());
}
$diff->attachArcanistProject($project);
}
return $diffs;
}
private function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();
if ($this->ids) {
$where[] = qsprintf(
$conn_r,
'id IN (%Ld)',
$this->ids);
}
if ($this->phids) {
$where[] = qsprintf(
$conn_r,
'phid IN (%Ls)',
$this->phids);
}
if ($this->revisionIDs) {
$where[] = qsprintf(
$conn_r,
'revisionID IN (%Ld)',
$this->revisionIDs);
}
$where[] = $this->buildPagingClause($conn_r);
return $this->formatWhereClause($where);
}
public function getQueryApplicationClass() {
return 'PhabricatorDifferentialApplication';
}
}
diff --git a/src/applications/differential/query/DifferentialHunkQuery.php b/src/applications/differential/query/DifferentialHunkQuery.php
index 98a9fcc3ba..68c1ba1100 100644
--- a/src/applications/differential/query/DifferentialHunkQuery.php
+++ b/src/applications/differential/query/DifferentialHunkQuery.php
@@ -1,119 +1,119 @@
<?php
final class DifferentialHunkQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
private $changesets;
private $shouldAttachToChangesets;
public function withChangesets(array $changesets) {
assert_instances_of($changesets, 'DifferentialChangeset');
$this->changesets = $changesets;
return $this;
}
public function needAttachToChangesets($attach) {
$this->shouldAttachToChangesets = $attach;
return $this;
}
- public function willExecute() {
+ protected function willExecute() {
// If we fail to load any hunks at all (for example, because all of
// the requested changesets are directories or empty files and have no
// hunks) we'll never call didFilterPage(), and thus never have an
// opportunity to attach hunks. Attach empty hunk lists now so that we
// end up with the right result.
if ($this->shouldAttachToChangesets) {
foreach ($this->changesets as $changeset) {
$changeset->attachHunks(array());
}
}
}
- public function loadPage() {
+ protected function loadPage() {
$all_results = array();
// Load modern hunks.
$table = new DifferentialHunkModern();
$conn_r = $table->establishConnection('r');
$modern_data = queryfx_all(
$conn_r,
'SELECT * FROM %T %Q %Q %Q',
$table->getTableName(),
$this->buildWhereClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
$modern_results = $table->loadAllFromArray($modern_data);
// Now, load legacy hunks.
$table = new DifferentialHunkLegacy();
$conn_r = $table->establishConnection('r');
$legacy_data = queryfx_all(
$conn_r,
'SELECT * FROM %T %Q %Q %Q',
$table->getTableName(),
$this->buildWhereClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
$legacy_results = $table->loadAllFromArray($legacy_data);
// Strip all the IDs off since they're not unique and nothing should be
// using them.
return array_values(array_merge($legacy_results, $modern_results));
}
- public function willFilterPage(array $hunks) {
+ protected function willFilterPage(array $hunks) {
$changesets = mpull($this->changesets, null, 'getID');
foreach ($hunks as $key => $hunk) {
$changeset = idx($changesets, $hunk->getChangesetID());
if (!$changeset) {
unset($hunks[$key]);
}
$hunk->attachChangeset($changeset);
}
return $hunks;
}
- public function didFilterPage(array $hunks) {
+ protected function didFilterPage(array $hunks) {
if ($this->shouldAttachToChangesets) {
$hunk_groups = mgroup($hunks, 'getChangesetID');
foreach ($this->changesets as $changeset) {
$hunks = idx($hunk_groups, $changeset->getID(), array());
$changeset->attachHunks($hunks);
}
}
return $hunks;
}
private function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();
if (!$this->changesets) {
throw new Exception(
pht('You must load hunks via changesets, with withChangesets()!'));
}
$where[] = qsprintf(
$conn_r,
'changesetID IN (%Ld)',
mpull($this->changesets, 'getID'));
$where[] = $this->buildPagingClause($conn_r);
return $this->formatWhereClause($where);
}
public function getQueryApplicationClass() {
return 'PhabricatorDifferentialApplication';
}
protected function getReversePaging() {
return true;
}
}
diff --git a/src/applications/differential/query/DifferentialRevisionQuery.php b/src/applications/differential/query/DifferentialRevisionQuery.php
index 7bfadf9da1..ef9712b644 100644
--- a/src/applications/differential/query/DifferentialRevisionQuery.php
+++ b/src/applications/differential/query/DifferentialRevisionQuery.php
@@ -1,1169 +1,1169 @@
<?php
/**
* Flexible query API for Differential revisions. Example:
*
* // Load open revisions
* $revisions = id(new DifferentialRevisionQuery())
* ->withStatus(DifferentialRevisionQuery::STATUS_OPEN)
* ->execute();
*
* @task config Query Configuration
* @task exec Query Execution
* @task internal Internals
*/
final class DifferentialRevisionQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
private $pathIDs = array();
private $status = 'status-any';
const STATUS_ANY = 'status-any';
const STATUS_OPEN = 'status-open';
const STATUS_ACCEPTED = 'status-accepted';
const STATUS_NEEDS_REVIEW = 'status-needs-review';
const STATUS_NEEDS_REVISION = 'status-needs-revision';
const STATUS_CLOSED = 'status-closed';
const STATUS_ABANDONED = 'status-abandoned';
private $authors = array();
private $draftAuthors = array();
private $ccs = array();
private $reviewers = array();
private $revIDs = array();
private $commitHashes = array();
private $phids = array();
private $responsibles = array();
private $branches = array();
private $arcanistProjectPHIDs = array();
private $repositoryPHIDs;
private $order = 'order-modified';
const ORDER_MODIFIED = 'order-modified';
const ORDER_CREATED = 'order-created';
/**
* This is essentially a denormalized copy of the revision modified time that
* should perform better for path queries with a LIMIT. Critically, when you
* browse "/", every revision in that repository for all time will match so
* the query benefits from being able to stop before fully materializing the
* result set.
*/
const ORDER_PATH_MODIFIED = 'order-path-modified';
private $needRelationships = false;
private $needActiveDiffs = false;
private $needDiffIDs = false;
private $needCommitPHIDs = false;
private $needHashes = false;
private $needReviewerStatus = false;
private $needReviewerAuthority;
private $needDrafts;
private $needFlags;
private $buildingGlobalOrder;
/* -( Query Configuration )------------------------------------------------ */
/**
* Filter results to revisions which affect a Diffusion path ID in a given
* repository. You can call this multiple times to select revisions for
* several paths.
*
* @param int Diffusion repository ID.
* @param int Diffusion path ID.
* @return this
* @task config
*/
public function withPath($repository_id, $path_id) {
$this->pathIDs[] = array(
'repositoryID' => $repository_id,
'pathID' => $path_id,
);
return $this;
}
/**
* Filter results to revisions authored by one of the given PHIDs. Calling
* this function will clear anything set by previous calls to
* @{method:withAuthors}.
*
* @param array List of PHIDs of authors
* @return this
* @task config
*/
public function withAuthors(array $author_phids) {
$this->authors = $author_phids;
return $this;
}
/**
* Filter results to revisions with comments authored by the given PHIDs.
*
* @param array List of PHIDs of authors
* @return this
* @task config
*/
public function withDraftRepliesByAuthors(array $author_phids) {
$this->draftAuthors = $author_phids;
return $this;
}
/**
* Filter results to revisions which CC one of the listed people. Calling this
* function will clear anything set by previous calls to @{method:withCCs}.
*
* @param array List of PHIDs of subscribers.
* @return this
* @task config
*/
public function withCCs(array $cc_phids) {
$this->ccs = $cc_phids;
return $this;
}
/**
* Filter results to revisions that have one of the provided PHIDs as
* reviewers. Calling this function will clear anything set by previous calls
* to @{method:withReviewers}.
*
* @param array List of PHIDs of reviewers
* @return this
* @task config
*/
public function withReviewers(array $reviewer_phids) {
$this->reviewers = $reviewer_phids;
return $this;
}
/**
* Filter results to revisions that have one of the provided commit hashes.
* Calling this function will clear anything set by previous calls to
* @{method:withCommitHashes}.
*
* @param array List of pairs <Class
* ArcanistDifferentialRevisionHash::HASH_$type constant,
* hash>
* @return this
* @task config
*/
public function withCommitHashes(array $commit_hashes) {
$this->commitHashes = $commit_hashes;
return $this;
}
/**
* Filter results to revisions with a given status. Provide a class constant,
* such as `DifferentialRevisionQuery::STATUS_OPEN`.
*
* @param const Class STATUS constant, like STATUS_OPEN.
* @return this
* @task config
*/
public function withStatus($status_constant) {
$this->status = $status_constant;
return $this;
}
/**
* Filter results to revisions on given branches.
*
* @param list List of branch names.
* @return this
* @task config
*/
public function withBranches(array $branches) {
$this->branches = $branches;
return $this;
}
/**
* Filter results to only return revisions whose ids are in the given set.
*
* @param array List of revision ids
* @return this
* @task config
*/
public function withIDs(array $ids) {
$this->revIDs = $ids;
return $this;
}
/**
* Filter results to only return revisions whose PHIDs are in the given set.
*
* @param array List of revision PHIDs
* @return this
* @task config
*/
public function withPHIDs(array $phids) {
$this->phids = $phids;
return $this;
}
/**
* Given a set of users, filter results to return only revisions they are
* responsible for (i.e., they are either authors or reviewers).
*
* @param array List of user PHIDs.
* @return this
* @task config
*/
public function withResponsibleUsers(array $responsible_phids) {
$this->responsibles = $responsible_phids;
return $this;
}
/**
* Filter results to only return revisions with a given set of arcanist
* projects.
*
* @param array List of project PHIDs.
* @return this
* @task config
*/
public function withArcanistProjectPHIDs(array $arc_project_phids) {
$this->arcanistProjectPHIDs = $arc_project_phids;
return $this;
}
public function withRepositoryPHIDs(array $repository_phids) {
$this->repositoryPHIDs = $repository_phids;
return $this;
}
/**
* Set result ordering. Provide a class constant, such as
* `DifferentialRevisionQuery::ORDER_CREATED`.
*
* @task config
*/
public function setOrder($order_constant) {
$this->order = $order_constant;
return $this;
}
/**
* Set whether or not the query will load and attach relationships.
*
* @param bool True to load and attach relationships.
* @return this
* @task config
*/
public function needRelationships($need_relationships) {
$this->needRelationships = $need_relationships;
return $this;
}
/**
* Set whether or not the query should load the active diff for each
* revision.
*
* @param bool True to load and attach diffs.
* @return this
* @task config
*/
public function needActiveDiffs($need_active_diffs) {
$this->needActiveDiffs = $need_active_diffs;
return $this;
}
/**
* Set whether or not the query should load the associated commit PHIDs for
* each revision.
*
* @param bool True to load and attach diffs.
* @return this
* @task config
*/
public function needCommitPHIDs($need_commit_phids) {
$this->needCommitPHIDs = $need_commit_phids;
return $this;
}
/**
* Set whether or not the query should load associated diff IDs for each
* revision.
*
* @param bool True to load and attach diff IDs.
* @return this
* @task config
*/
public function needDiffIDs($need_diff_ids) {
$this->needDiffIDs = $need_diff_ids;
return $this;
}
/**
* Set whether or not the query should load associated commit hashes for each
* revision.
*
* @param bool True to load and attach commit hashes.
* @return this
* @task config
*/
public function needHashes($need_hashes) {
$this->needHashes = $need_hashes;
return $this;
}
/**
* Set whether or not the query should load associated reviewer status.
*
* @param bool True to load and attach reviewers.
* @return this
* @task config
*/
public function needReviewerStatus($need_reviewer_status) {
$this->needReviewerStatus = $need_reviewer_status;
return $this;
}
/**
* Request information about the viewer's authority to act on behalf of each
* reviewer. In particular, they have authority to act on behalf of projects
* they are a member of.
*
* @param bool True to load and attach authority.
* @return this
* @task config
*/
public function needReviewerAuthority($need_reviewer_authority) {
$this->needReviewerAuthority = $need_reviewer_authority;
return $this;
}
public function needFlags($need_flags) {
$this->needFlags = $need_flags;
return $this;
}
public function needDrafts($need_drafts) {
$this->needDrafts = $need_drafts;
return $this;
}
/* -( Query Execution )---------------------------------------------------- */
/**
* Execute the query as configured, returning matching
* @{class:DifferentialRevision} objects.
*
* @return list List of matching DifferentialRevision objects.
* @task exec
*/
- public function loadPage() {
+ protected function loadPage() {
$table = new DifferentialRevision();
$conn_r = $table->establishConnection('r');
$data = $this->loadData();
return $table->loadAllFromArray($data);
}
- public function willFilterPage(array $revisions) {
+ protected function willFilterPage(array $revisions) {
$viewer = $this->getViewer();
$repository_phids = mpull($revisions, 'getRepositoryPHID');
$repository_phids = array_filter($repository_phids);
$repositories = array();
if ($repository_phids) {
$repositories = id(new PhabricatorRepositoryQuery())
->setViewer($this->getViewer())
->withPHIDs($repository_phids)
->execute();
$repositories = mpull($repositories, null, 'getPHID');
}
// If a revision is associated with a repository:
//
// - the viewer must be able to see the repository; or
// - the viewer must have an automatic view capability.
//
// In the latter case, we'll load the revision but not load the repository.
$can_view = PhabricatorPolicyCapability::CAN_VIEW;
foreach ($revisions as $key => $revision) {
$repo_phid = $revision->getRepositoryPHID();
if (!$repo_phid) {
// The revision has no associated repository. Attach `null` and move on.
$revision->attachRepository(null);
continue;
}
$repository = idx($repositories, $repo_phid);
if ($repository) {
// The revision has an associated repository, and the viewer can see
// it. Attach it and move on.
$revision->attachRepository($repository);
continue;
}
if ($revision->hasAutomaticCapability($can_view, $viewer)) {
// The revision has an associated repository which the viewer can not
// see, but the viewer has an automatic capability on this revision.
// Load the revision without attaching a repository.
$revision->attachRepository(null);
continue;
}
if ($this->getViewer()->isOmnipotent()) {
// The viewer is omnipotent. Allow the revision to load even without
// a repository.
$revision->attachRepository(null);
continue;
}
// The revision has an associated repository, and the viewer can't see
// it, and the viewer has no special capabilities. Filter out this
// revision.
$this->didRejectResult($revision);
unset($revisions[$key]);
}
if (!$revisions) {
return array();
}
$table = new DifferentialRevision();
$conn_r = $table->establishConnection('r');
if ($this->needRelationships) {
$this->loadRelationships($conn_r, $revisions);
}
if ($this->needCommitPHIDs) {
$this->loadCommitPHIDs($conn_r, $revisions);
}
$need_active = $this->needActiveDiffs;
$need_ids = $need_active || $this->needDiffIDs;
if ($need_ids) {
$this->loadDiffIDs($conn_r, $revisions);
}
if ($need_active) {
$this->loadActiveDiffs($conn_r, $revisions);
}
if ($this->needHashes) {
$this->loadHashes($conn_r, $revisions);
}
if ($this->needReviewerStatus || $this->needReviewerAuthority) {
$this->loadReviewers($conn_r, $revisions);
}
return $revisions;
}
protected function didFilterPage(array $revisions) {
$viewer = $this->getViewer();
if ($this->needFlags) {
$flags = id(new PhabricatorFlagQuery())
->setViewer($viewer)
->withOwnerPHIDs(array($viewer->getPHID()))
->withObjectPHIDs(mpull($revisions, 'getPHID'))
->execute();
$flags = mpull($flags, null, 'getObjectPHID');
foreach ($revisions as $revision) {
$revision->attachFlag(
$viewer,
idx($flags, $revision->getPHID()));
}
}
if ($this->needDrafts) {
$drafts = id(new DifferentialDraft())->loadAllWhere(
'authorPHID = %s AND objectPHID IN (%Ls)',
$viewer->getPHID(),
mpull($revisions, 'getPHID'));
$drafts = mgroup($drafts, 'getObjectPHID');
foreach ($revisions as $revision) {
$revision->attachDrafts(
$viewer,
idx($drafts, $revision->getPHID(), array()));
}
}
return $revisions;
}
private function loadData() {
$table = new DifferentialRevision();
$conn_r = $table->establishConnection('r');
$selects = array();
// NOTE: If the query includes "responsiblePHIDs", we execute it as a
// UNION of revisions they own and revisions they're reviewing. This has
// much better performance than doing it with JOIN/WHERE.
if ($this->responsibles) {
$basic_authors = $this->authors;
$basic_reviewers = $this->reviewers;
$authority_projects = id(new PhabricatorProjectQuery())
->setViewer($this->getViewer())
->withMemberPHIDs($this->responsibles)
->execute();
$authority_phids = mpull($authority_projects, 'getPHID');
try {
// Build the query where the responsible users are authors.
$this->authors = array_merge($basic_authors, $this->responsibles);
$this->reviewers = $basic_reviewers;
$selects[] = $this->buildSelectStatement($conn_r);
// Build the query where the responsible users are reviewers, or
// projects they are members of are reviewers.
$this->authors = $basic_authors;
$this->reviewers = array_merge(
$basic_reviewers,
$this->responsibles,
$authority_phids);
$selects[] = $this->buildSelectStatement($conn_r);
// Put everything back like it was.
$this->authors = $basic_authors;
$this->reviewers = $basic_reviewers;
} catch (Exception $ex) {
$this->authors = $basic_authors;
$this->reviewers = $basic_reviewers;
throw $ex;
}
} else {
$selects[] = $this->buildSelectStatement($conn_r);
}
if (count($selects) > 1) {
$this->buildingGlobalOrder = true;
$query = qsprintf(
$conn_r,
'%Q %Q %Q',
implode(' UNION DISTINCT ', $selects),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
} else {
$query = head($selects);
}
return queryfx_all($conn_r, '%Q', $query);
}
private function buildSelectStatement(AphrontDatabaseConnection $conn_r) {
$table = new DifferentialRevision();
$select = qsprintf(
$conn_r,
'SELECT r.* FROM %T r',
$table->getTableName());
$joins = $this->buildJoinsClause($conn_r);
$where = $this->buildWhereClause($conn_r);
$group_by = $this->buildGroupByClause($conn_r);
$this->buildingGlobalOrder = false;
$order_by = $this->buildOrderClause($conn_r);
$limit = $this->buildLimitClause($conn_r);
return qsprintf(
$conn_r,
'(%Q %Q %Q %Q %Q %Q)',
$select,
$joins,
$where,
$group_by,
$order_by,
$limit);
}
/* -( Internals )---------------------------------------------------------- */
/**
* @task internal
*/
private function buildJoinsClause($conn_r) {
$joins = array();
if ($this->pathIDs) {
$path_table = new DifferentialAffectedPath();
$joins[] = qsprintf(
$conn_r,
'JOIN %T p ON p.revisionID = r.id',
$path_table->getTableName());
}
if ($this->commitHashes) {
$joins[] = qsprintf(
$conn_r,
'JOIN %T hash_rel ON hash_rel.revisionID = r.id',
ArcanistDifferentialRevisionHash::TABLE_NAME);
}
if ($this->ccs) {
$joins[] = qsprintf(
$conn_r,
'JOIN %T e_ccs ON e_ccs.src = r.phid '.
'AND e_ccs.type = %s '.
'AND e_ccs.dst in (%Ls)',
PhabricatorEdgeConfig::TABLE_NAME_EDGE,
PhabricatorObjectHasSubscriberEdgeType::EDGECONST,
$this->ccs);
}
if ($this->reviewers) {
$joins[] = qsprintf(
$conn_r,
'JOIN %T e_reviewers ON e_reviewers.src = r.phid '.
'AND e_reviewers.type = %s '.
'AND e_reviewers.dst in (%Ls)',
PhabricatorEdgeConfig::TABLE_NAME_EDGE,
DifferentialRevisionHasReviewerEdgeType::EDGECONST,
$this->reviewers);
}
if ($this->draftAuthors) {
$differential_draft = new DifferentialDraft();
$joins[] = qsprintf(
$conn_r,
'JOIN %T has_draft ON has_draft.objectPHID = r.phid '.
'AND has_draft.authorPHID IN (%Ls)',
$differential_draft->getTableName(),
$this->draftAuthors);
}
$joins = implode(' ', $joins);
return $joins;
}
/**
* @task internal
*/
private function buildWhereClause($conn_r) {
$where = array();
if ($this->pathIDs) {
$path_clauses = array();
$repo_info = igroup($this->pathIDs, 'repositoryID');
foreach ($repo_info as $repository_id => $paths) {
$path_clauses[] = qsprintf(
$conn_r,
'(p.repositoryID = %d AND p.pathID IN (%Ld))',
$repository_id,
ipull($paths, 'pathID'));
}
$path_clauses = '('.implode(' OR ', $path_clauses).')';
$where[] = $path_clauses;
}
if ($this->authors) {
$where[] = qsprintf(
$conn_r,
'r.authorPHID IN (%Ls)',
$this->authors);
}
if ($this->revIDs) {
$where[] = qsprintf(
$conn_r,
'r.id IN (%Ld)',
$this->revIDs);
}
if ($this->repositoryPHIDs) {
$where[] = qsprintf(
$conn_r,
'r.repositoryPHID IN (%Ls)',
$this->repositoryPHIDs);
}
if ($this->commitHashes) {
$hash_clauses = array();
foreach ($this->commitHashes as $info) {
list($type, $hash) = $info;
$hash_clauses[] = qsprintf(
$conn_r,
'(hash_rel.type = %s AND hash_rel.hash = %s)',
$type,
$hash);
}
$hash_clauses = '('.implode(' OR ', $hash_clauses).')';
$where[] = $hash_clauses;
}
if ($this->phids) {
$where[] = qsprintf(
$conn_r,
'r.phid IN (%Ls)',
$this->phids);
}
if ($this->branches) {
$where[] = qsprintf(
$conn_r,
'r.branchName in (%Ls)',
$this->branches);
}
if ($this->arcanistProjectPHIDs) {
$where[] = qsprintf(
$conn_r,
'r.arcanistProjectPHID in (%Ls)',
$this->arcanistProjectPHIDs);
}
switch ($this->status) {
case self::STATUS_ANY:
break;
case self::STATUS_OPEN:
$where[] = qsprintf(
$conn_r,
'r.status IN (%Ld)',
DifferentialRevisionStatus::getOpenStatuses());
break;
case self::STATUS_NEEDS_REVIEW:
$where[] = qsprintf(
$conn_r,
'r.status IN (%Ld)',
array(
ArcanistDifferentialRevisionStatus::NEEDS_REVIEW,
));
break;
case self::STATUS_NEEDS_REVISION:
$where[] = qsprintf(
$conn_r,
'r.status IN (%Ld)',
array(
ArcanistDifferentialRevisionStatus::NEEDS_REVISION,
));
break;
case self::STATUS_ACCEPTED:
$where[] = qsprintf(
$conn_r,
'r.status IN (%Ld)',
array(
ArcanistDifferentialRevisionStatus::ACCEPTED,
));
break;
case self::STATUS_CLOSED:
$where[] = qsprintf(
$conn_r,
'r.status IN (%Ld)',
DifferentialRevisionStatus::getClosedStatuses());
break;
case self::STATUS_ABANDONED:
$where[] = qsprintf(
$conn_r,
'r.status IN (%Ld)',
array(
ArcanistDifferentialRevisionStatus::ABANDONED,
));
break;
default:
throw new Exception(
"Unknown revision status filter constant '{$this->status}'!");
}
$where[] = $this->buildPagingClause($conn_r);
return $this->formatWhereClause($where);
}
/**
* @task internal
*/
private function buildGroupByClause($conn_r) {
$join_triggers = array_merge(
$this->pathIDs,
$this->ccs,
$this->reviewers);
$needs_distinct = (count($join_triggers) > 1);
if ($needs_distinct) {
return 'GROUP BY r.id';
} else {
return '';
}
}
private function loadCursorObject($id) {
$results = id(new DifferentialRevisionQuery())
->setViewer($this->getPagingViewer())
->withIDs(array((int)$id))
->execute();
return head($results);
}
protected function buildPagingClause(AphrontDatabaseConnection $conn_r) {
$default = parent::buildPagingClause($conn_r);
$before_id = $this->getBeforeID();
$after_id = $this->getAfterID();
if (!$before_id && !$after_id) {
return $default;
}
if ($before_id) {
$cursor = $this->loadCursorObject($before_id);
} else {
$cursor = $this->loadCursorObject($after_id);
}
if (!$cursor) {
return null;
}
$columns = array();
switch ($this->order) {
case self::ORDER_CREATED:
return $default;
case self::ORDER_MODIFIED:
$columns[] = array(
'name' => 'r.dateModified',
'value' => $cursor->getDateModified(),
'type' => 'int',
);
break;
case self::ORDER_PATH_MODIFIED:
$columns[] = array(
'name' => 'p.epoch',
'value' => $cursor->getDateCreated(),
'type' => 'int',
);
break;
}
$columns[] = array(
'name' => 'r.id',
'value' => $cursor->getID(),
'type' => 'int',
);
return $this->buildPagingClauseFromMultipleColumns(
$conn_r,
$columns,
array(
'reversed' => (bool)($before_id xor $this->getReversePaging()),
));
}
protected function getPagingColumn() {
$is_global = $this->buildingGlobalOrder;
switch ($this->order) {
case self::ORDER_MODIFIED:
if ($is_global) {
return 'dateModified';
}
return 'r.dateModified';
case self::ORDER_CREATED:
if ($is_global) {
return 'id';
}
return 'r.id';
case self::ORDER_PATH_MODIFIED:
if (!$this->pathIDs) {
throw new Exception(
'To use ORDER_PATH_MODIFIED, you must specify withPath().');
}
return 'p.epoch';
default:
throw new Exception("Unknown query order constant '{$this->order}'.");
}
}
private function loadRelationships($conn_r, array $revisions) {
assert_instances_of($revisions, 'DifferentialRevision');
$type_reviewer = DifferentialRevisionHasReviewerEdgeType::EDGECONST;
$type_subscriber = PhabricatorObjectHasSubscriberEdgeType::EDGECONST;
$edges = id(new PhabricatorEdgeQuery())
->withSourcePHIDs(mpull($revisions, 'getPHID'))
->withEdgeTypes(array($type_reviewer, $type_subscriber))
->setOrder(PhabricatorEdgeQuery::ORDER_OLDEST_FIRST)
->execute();
$type_map = array(
DifferentialRevision::RELATION_REVIEWER => $type_reviewer,
DifferentialRevision::RELATION_SUBSCRIBED => $type_subscriber,
);
foreach ($revisions as $revision) {
$data = array();
foreach ($type_map as $rel_type => $edge_type) {
$revision_edges = $edges[$revision->getPHID()][$edge_type];
foreach ($revision_edges as $dst_phid => $edge_data) {
$data[] = array(
'relation' => $rel_type,
'objectPHID' => $dst_phid,
'reasonPHID' => null,
);
}
}
$revision->attachRelationships($data);
}
}
private function loadCommitPHIDs($conn_r, array $revisions) {
assert_instances_of($revisions, 'DifferentialRevision');
$commit_phids = queryfx_all(
$conn_r,
'SELECT * FROM %T WHERE revisionID IN (%Ld)',
DifferentialRevision::TABLE_COMMIT,
mpull($revisions, 'getID'));
$commit_phids = igroup($commit_phids, 'revisionID');
foreach ($revisions as $revision) {
$phids = idx($commit_phids, $revision->getID(), array());
$phids = ipull($phids, 'commitPHID');
$revision->attachCommitPHIDs($phids);
}
}
private function loadDiffIDs($conn_r, array $revisions) {
assert_instances_of($revisions, 'DifferentialRevision');
$diff_table = new DifferentialDiff();
$diff_ids = queryfx_all(
$conn_r,
'SELECT revisionID, id FROM %T WHERE revisionID IN (%Ld)
ORDER BY id DESC',
$diff_table->getTableName(),
mpull($revisions, 'getID'));
$diff_ids = igroup($diff_ids, 'revisionID');
foreach ($revisions as $revision) {
$ids = idx($diff_ids, $revision->getID(), array());
$ids = ipull($ids, 'id');
$revision->attachDiffIDs($ids);
}
}
private function loadActiveDiffs($conn_r, array $revisions) {
assert_instances_of($revisions, 'DifferentialRevision');
$diff_table = new DifferentialDiff();
$load_ids = array();
foreach ($revisions as $revision) {
$diffs = $revision->getDiffIDs();
if ($diffs) {
$load_ids[] = max($diffs);
}
}
$active_diffs = array();
if ($load_ids) {
$active_diffs = $diff_table->loadAllWhere(
'id IN (%Ld)',
$load_ids);
}
$active_diffs = mpull($active_diffs, null, 'getRevisionID');
foreach ($revisions as $revision) {
$revision->attachActiveDiff(idx($active_diffs, $revision->getID()));
}
}
private function loadHashes(
AphrontDatabaseConnection $conn_r,
array $revisions) {
assert_instances_of($revisions, 'DifferentialRevision');
$data = queryfx_all(
$conn_r,
'SELECT * FROM %T WHERE revisionID IN (%Ld)',
'differential_revisionhash',
mpull($revisions, 'getID'));
$data = igroup($data, 'revisionID');
foreach ($revisions as $revision) {
$hashes = idx($data, $revision->getID(), array());
$list = array();
foreach ($hashes as $hash) {
$list[] = array($hash['type'], $hash['hash']);
}
$revision->attachHashes($list);
}
}
private function loadReviewers(
AphrontDatabaseConnection $conn_r,
array $revisions) {
assert_instances_of($revisions, 'DifferentialRevision');
$edge_type = DifferentialRevisionHasReviewerEdgeType::EDGECONST;
$edges = id(new PhabricatorEdgeQuery())
->withSourcePHIDs(mpull($revisions, 'getPHID'))
->withEdgeTypes(array($edge_type))
->needEdgeData(true)
->setOrder(PhabricatorEdgeQuery::ORDER_OLDEST_FIRST)
->execute();
$viewer = $this->getViewer();
$viewer_phid = $viewer->getPHID();
$allow_key = 'differential.allow-self-accept';
$allow_self = PhabricatorEnv::getEnvConfig($allow_key);
// Figure out which of these reviewers the viewer has authority to act as.
if ($this->needReviewerAuthority && $viewer_phid) {
$authority = $this->loadReviewerAuthority(
$revisions,
$edges,
$allow_self);
}
foreach ($revisions as $revision) {
$revision_edges = $edges[$revision->getPHID()][$edge_type];
$reviewers = array();
foreach ($revision_edges as $reviewer_phid => $edge) {
$reviewer = new DifferentialReviewer($reviewer_phid, $edge['data']);
if ($this->needReviewerAuthority) {
if (!$viewer_phid) {
// Logged-out users never have authority.
$has_authority = false;
} else if ((!$allow_self) &&
($revision->getAuthorPHID() == $viewer_phid)) {
// The author can never have authority unless we allow self-accept.
$has_authority = false;
} else {
// Otherwise, look up whether th viewer has authority.
$has_authority = isset($authority[$reviewer_phid]);
}
$reviewer->attachAuthority($viewer, $has_authority);
}
$reviewers[$reviewer_phid] = $reviewer;
}
$revision->attachReviewerStatus($reviewers);
}
}
public static function splitResponsible(array $revisions, array $user_phids) {
$blocking = array();
$active = array();
$waiting = array();
$status_review = ArcanistDifferentialRevisionStatus::NEEDS_REVIEW;
// Bucket revisions into $blocking (revisions where you are blocking
// others), $active (revisions you need to do something about) and $waiting
// (revisions you're waiting on someone else to do something about).
foreach ($revisions as $revision) {
$needs_review = ($revision->getStatus() == $status_review);
$filter_is_author = in_array($revision->getAuthorPHID(), $user_phids);
if (!$revision->getReviewers()) {
$needs_review = false;
$author_is_reviewer = false;
} else {
$author_is_reviewer = in_array(
$revision->getAuthorPHID(),
$revision->getReviewers());
}
// If exactly one of "needs review" and "the user is the author" is
// true, the user needs to act on it. Otherwise, they're waiting on
// it.
if ($needs_review ^ $filter_is_author) {
if ($needs_review) {
array_unshift($blocking, $revision);
} else {
$active[] = $revision;
}
// User is author **and** reviewer. An exotic but configurable workflow.
// User needs to act on it double.
} else if ($needs_review && $author_is_reviewer) {
array_unshift($blocking, $revision);
$active[] = $revision;
} else {
$waiting[] = $revision;
}
}
return array($blocking, $active, $waiting);
}
private function loadReviewerAuthority(
array $revisions,
array $edges,
$allow_self) {
$revision_map = mpull($revisions, null, 'getPHID');
$viewer_phid = $this->getViewer()->getPHID();
// Find all the project reviewers which the user may have authority over.
$project_phids = array();
$project_type = PhabricatorProjectProjectPHIDType::TYPECONST;
$edge_type = DifferentialRevisionHasReviewerEdgeType::EDGECONST;
foreach ($edges as $src => $types) {
if (!$allow_self) {
if ($revision_map[$src]->getAuthorPHID() == $viewer_phid) {
// If self-review isn't permitted, the user will never have
// authority over projects on revisions they authored because you
// can't accept your own revisions, so we don't need to load any
// data about these reviewers.
continue;
}
}
$edge_data = idx($types, $edge_type, array());
foreach ($edge_data as $dst => $data) {
if (phid_get_type($dst) == $project_type) {
$project_phids[] = $dst;
}
}
}
// Now, figure out which of these projects the viewer is actually a
// member of.
$project_authority = array();
if ($project_phids) {
$project_authority = id(new PhabricatorProjectQuery())
->setViewer($this->getViewer())
->withPHIDs($project_phids)
->withMemberPHIDs(array($viewer_phid))
->execute();
$project_authority = mpull($project_authority, 'getPHID');
}
// Finally, the viewer has authority over themselves.
return array(
$viewer_phid => true,
) + array_fuse($project_authority);
}
public function getQueryApplicationClass() {
return 'PhabricatorDifferentialApplication';
}
}
diff --git a/src/applications/diffusion/query/DiffusionCommitQuery.php b/src/applications/diffusion/query/DiffusionCommitQuery.php
index edd3484ec0..8abb67b99f 100644
--- a/src/applications/diffusion/query/DiffusionCommitQuery.php
+++ b/src/applications/diffusion/query/DiffusionCommitQuery.php
@@ -1,566 +1,566 @@
<?php
final class DiffusionCommitQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
private $ids;
private $phids;
private $authorPHIDs;
private $defaultRepository;
private $identifiers;
private $repositoryIDs;
private $repositoryPHIDs;
private $identifierMap;
private $needAuditRequests;
private $auditIDs;
private $auditorPHIDs;
private $auditAwaitingUser;
private $auditStatus;
const AUDIT_STATUS_ANY = 'audit-status-any';
const AUDIT_STATUS_OPEN = 'audit-status-open';
const AUDIT_STATUS_CONCERN = 'audit-status-concern';
const AUDIT_STATUS_ACCEPTED = 'audit-status-accepted';
const AUDIT_STATUS_PARTIAL = 'audit-status-partial';
private $needCommitData;
public function withIDs(array $ids) {
$this->ids = $ids;
return $this;
}
public function withPHIDs(array $phids) {
$this->phids = $phids;
return $this;
}
public function withAuthorPHIDs(array $phids) {
$this->authorPHIDs = $phids;
return $this;
}
/**
* Load commits by partial or full identifiers, e.g. "rXab82393", "rX1234",
* or "a9caf12". When an identifier matches multiple commits, they will all
* be returned; callers should be prepared to deal with more results than
* they queried for.
*/
public function withIdentifiers(array $identifiers) {
$this->identifiers = $identifiers;
return $this;
}
/**
* Look up commits in a specific repository. This is a shorthand for calling
* @{method:withDefaultRepository} and @{method:withRepositoryIDs}.
*/
public function withRepository(PhabricatorRepository $repository) {
$this->withDefaultRepository($repository);
$this->withRepositoryIDs(array($repository->getID()));
return $this;
}
/**
* Look up commits in a specific repository. Prefer
* @{method:withRepositoryIDs}; the underyling table is keyed by ID such
* that this method requires a separate initial query to map PHID to ID.
*/
public function withRepositoryPHIDs(array $phids) {
$this->repositoryPHIDs = $phids;
}
/**
* If a default repository is provided, ambiguous commit identifiers will
* be assumed to belong to the default repository.
*
* For example, "r123" appearing in a commit message in repository X is
* likely to be unambiguously "rX123". Normally the reference would be
* considered ambiguous, but if you provide a default repository it will
* be correctly resolved.
*/
public function withDefaultRepository(PhabricatorRepository $repository) {
$this->defaultRepository = $repository;
return $this;
}
public function withRepositoryIDs(array $repository_ids) {
$this->repositoryIDs = $repository_ids;
return $this;
}
public function needCommitData($need) {
$this->needCommitData = $need;
return $this;
}
public function needAuditRequests($need) {
$this->needAuditRequests = $need;
return $this;
}
/**
* Returns true if we should join the audit table, either because we're
* interested in the information if it's available or because matching rows
* must always have it.
*/
private function shouldJoinAudits() {
return $this->auditStatus ||
$this->rowsMustHaveAudits();
}
/**
* Return true if we should `JOIN` (vs `LEFT JOIN`) the audit table, because
* matching commits will always have audit rows.
*/
private function rowsMustHaveAudits() {
return
$this->auditIDs ||
$this->auditorPHIDs ||
$this->auditAwaitingUser;
}
public function withAuditIDs(array $ids) {
$this->auditIDs = $ids;
return $this;
}
public function withAuditorPHIDs(array $auditor_phids) {
$this->auditorPHIDs = $auditor_phids;
return $this;
}
public function withAuditAwaitingUser(PhabricatorUser $user) {
$this->auditAwaitingUser = $user;
return $this;
}
public function withAuditStatus($status) {
$this->auditStatus = $status;
return $this;
}
public function getIdentifierMap() {
if ($this->identifierMap === null) {
throw new Exception(
'You must execute() the query before accessing the identifier map.');
}
return $this->identifierMap;
}
protected function getPagingColumn() {
return 'commit.id';
}
protected function willExecute() {
if ($this->identifierMap === null) {
$this->identifierMap = array();
}
}
protected function loadPage() {
$table = new PhabricatorRepositoryCommit();
$conn_r = $table->establishConnection('r');
$data = queryfx_all(
$conn_r,
'SELECT commit.* FROM %T commit %Q %Q %Q %Q %Q',
$table->getTableName(),
$this->buildJoinClause($conn_r),
$this->buildWhereClause($conn_r),
$this->buildGroupClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
return $table->loadAllFromArray($data);
}
protected function willFilterPage(array $commits) {
$repository_ids = mpull($commits, 'getRepositoryID', 'getRepositoryID');
$repos = id(new PhabricatorRepositoryQuery())
->setViewer($this->getViewer())
->withIDs($repository_ids)
->execute();
$min_qualified = PhabricatorRepository::MINIMUM_QUALIFIED_HASH;
$result = array();
foreach ($commits as $key => $commit) {
$repo = idx($repos, $commit->getRepositoryID());
if ($repo) {
$commit->attachRepository($repo);
} else {
unset($commits[$key]);
continue;
}
// Build the identifierMap
if ($this->identifiers !== null) {
$ids = array_fuse($this->identifiers);
$prefixes = array(
'r'.$commit->getRepository()->getCallsign(),
'r'.$commit->getRepository()->getCallsign().':',
'R'.$commit->getRepository()->getID().':',
'', // No prefix is valid too and will only match the commitIdentifier
);
$suffix = $commit->getCommitIdentifier();
if ($commit->getRepository()->isSVN()) {
foreach ($prefixes as $prefix) {
if (isset($ids[$prefix.$suffix])) {
$result[$prefix.$suffix][] = $commit;
}
}
} else {
// This awkward construction is so we can link the commits up in O(N)
// time instead of O(N^2).
for ($ii = $min_qualified; $ii <= strlen($suffix); $ii++) {
$part = substr($suffix, 0, $ii);
foreach ($prefixes as $prefix) {
if (isset($ids[$prefix.$part])) {
$result[$prefix.$part][] = $commit;
}
}
}
}
}
}
if ($result) {
foreach ($result as $identifier => $matching_commits) {
if (count($matching_commits) == 1) {
$result[$identifier] = head($matching_commits);
} else {
// This reference is ambiguous (it matches more than one commit) so
// don't link it.
unset($result[$identifier]);
}
}
$this->identifierMap += $result;
}
return $commits;
}
protected function didFilterPage(array $commits) {
if ($this->needCommitData) {
$data = id(new PhabricatorRepositoryCommitData())->loadAllWhere(
'commitID in (%Ld)',
mpull($commits, 'getID'));
$data = mpull($data, null, 'getCommitID');
foreach ($commits as $commit) {
$commit_data = idx($data, $commit->getID());
if (!$commit_data) {
$commit_data = new PhabricatorRepositoryCommitData();
}
$commit->attachCommitData($commit_data);
}
}
// TODO: This should just be `needAuditRequests`, not `shouldJoinAudits()`,
// but leave that for a future diff.
if ($this->needAuditRequests || $this->shouldJoinAudits()) {
$requests = id(new PhabricatorRepositoryAuditRequest())->loadAllWhere(
'commitPHID IN (%Ls)',
mpull($commits, 'getPHID'));
$requests = mgroup($requests, 'getCommitPHID');
foreach ($commits as $commit) {
$audit_requests = idx($requests, $commit->getPHID(), array());
$commit->attachAudits($audit_requests);
foreach ($audit_requests as $audit_request) {
$audit_request->attachCommit($commit);
}
}
}
return $commits;
}
private function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();
if ($this->repositoryPHIDs !== null) {
$map_repositories = id (new PhabricatorRepositoryQuery())
->setViewer($this->getViewer())
->withPHIDs($this->repositoryPHIDs)
->execute();
if (!$map_repositories) {
throw new PhabricatorEmptyQueryException();
}
$repository_ids = mpull($map_repositories, 'getID');
if ($this->repositoryIDs !== null) {
$repository_ids = array_merge($repository_ids, $this->repositoryIDs);
}
$this->withRepositoryIDs($repository_ids);
}
if ($this->ids !== null) {
$where[] = qsprintf(
$conn_r,
'commit.id IN (%Ld)',
$this->ids);
}
if ($this->phids !== null) {
$where[] = qsprintf(
$conn_r,
'commit.phid IN (%Ls)',
$this->phids);
}
if ($this->repositoryIDs !== null) {
$where[] = qsprintf(
$conn_r,
'commit.repositoryID IN (%Ld)',
$this->repositoryIDs);
}
if ($this->authorPHIDs !== null) {
$where[] = qsprintf(
$conn_r,
'commit.authorPHID IN (%Ls)',
$this->authorPHIDs);
}
if ($this->identifiers !== null) {
$min_unqualified = PhabricatorRepository::MINIMUM_UNQUALIFIED_HASH;
$min_qualified = PhabricatorRepository::MINIMUM_QUALIFIED_HASH;
$refs = array();
$bare = array();
foreach ($this->identifiers as $identifier) {
$matches = null;
preg_match('/^(?:[rR]([A-Z]+:?|[0-9]+:))?(.*)$/',
$identifier, $matches);
$repo = nonempty(rtrim($matches[1], ':'), null);
$commit_identifier = nonempty($matches[2], null);
if ($repo === null) {
if ($this->defaultRepository) {
$repo = $this->defaultRepository->getCallsign();
}
}
if ($repo === null) {
if (strlen($commit_identifier) < $min_unqualified) {
continue;
}
$bare[] = $commit_identifier;
} else {
$refs[] = array(
'callsign' => $repo,
'identifier' => $commit_identifier,
);
}
}
$sql = array();
foreach ($bare as $identifier) {
$sql[] = qsprintf(
$conn_r,
'(commit.commitIdentifier LIKE %> AND '.
'LENGTH(commit.commitIdentifier) = 40)',
$identifier);
}
if ($refs) {
$callsigns = ipull($refs, 'callsign');
$repos = id(new PhabricatorRepositoryQuery())
->setViewer($this->getViewer())
->withIdentifiers($callsigns);
$repos->execute();
$repos = $repos->getIdentifierMap();
foreach ($refs as $key => $ref) {
$repo = idx($repos, $ref['callsign']);
if (!$repo) {
continue;
}
if ($repo->isSVN()) {
if (!ctype_digit($ref['identifier'])) {
continue;
}
$sql[] = qsprintf(
$conn_r,
'(commit.repositoryID = %d AND commit.commitIdentifier = %s)',
$repo->getID(),
// NOTE: Because the 'commitIdentifier' column is a string, MySQL
// ignores the index if we hand it an integer. Hand it a string.
// See T3377.
(int)$ref['identifier']);
} else {
if (strlen($ref['identifier']) < $min_qualified) {
continue;
}
$sql[] = qsprintf(
$conn_r,
'(commit.repositoryID = %d AND commit.commitIdentifier LIKE %>)',
$repo->getID(),
$ref['identifier']);
}
}
}
if (!$sql) {
// If we discarded all possible identifiers (e.g., they all referenced
// bogus repositories or were all too short), make sure the query finds
// nothing.
throw new PhabricatorEmptyQueryException(
pht('No commit identifiers.'));
}
$where[] = '('.implode(' OR ', $sql).')';
}
if ($this->auditIDs !== null) {
$where[] = qsprintf(
$conn_r,
'audit.id IN (%Ld)',
$this->auditIDs);
}
if ($this->auditorPHIDs !== null) {
$where[] = qsprintf(
$conn_r,
'audit.auditorPHID IN (%Ls)',
$this->auditorPHIDs);
}
if ($this->auditAwaitingUser) {
$awaiting_user_phid = $this->auditAwaitingUser->getPHID();
// Exclude package and project audits associated with commits where
// the user is the author.
$where[] = qsprintf(
$conn_r,
'(commit.authorPHID IS NULL OR commit.authorPHID != %s)
OR (audit.auditorPHID = %s)',
$awaiting_user_phid,
$awaiting_user_phid);
}
$status = $this->auditStatus;
if ($status !== null) {
switch ($status) {
case self::AUDIT_STATUS_PARTIAL:
$where[] = qsprintf(
$conn_r,
'commit.auditStatus = %d',
PhabricatorAuditCommitStatusConstants::PARTIALLY_AUDITED);
break;
case self::AUDIT_STATUS_ACCEPTED:
$where[] = qsprintf(
$conn_r,
'commit.auditStatus = %d',
PhabricatorAuditCommitStatusConstants::FULLY_AUDITED);
break;
case self::AUDIT_STATUS_CONCERN:
$where[] = qsprintf(
$conn_r,
'audit.auditStatus = %s',
PhabricatorAuditStatusConstants::CONCERNED);
break;
case self::AUDIT_STATUS_OPEN:
$where[] = qsprintf(
$conn_r,
'audit.auditStatus in (%Ls)',
PhabricatorAuditStatusConstants::getOpenStatusConstants());
if ($this->auditAwaitingUser) {
$where[] = qsprintf(
$conn_r,
'awaiting.auditStatus IS NULL OR awaiting.auditStatus != %s',
PhabricatorAuditStatusConstants::RESIGNED);
}
break;
case self::AUDIT_STATUS_ANY:
break;
default:
$valid = array(
self::AUDIT_STATUS_ANY,
self::AUDIT_STATUS_OPEN,
self::AUDIT_STATUS_CONCERN,
self::AUDIT_STATUS_ACCEPTED,
self::AUDIT_STATUS_PARTIAL,
);
throw new Exception(
"Unknown audit status '{$status}'! Valid statuses are: ".
implode(', ', $valid));
}
}
$where[] = $this->buildPagingClause($conn_r);
return $this->formatWhereClause($where);
}
- public function didFilterResults(array $filtered) {
+ protected function didFilterResults(array $filtered) {
if ($this->identifierMap) {
foreach ($this->identifierMap as $name => $commit) {
if (isset($filtered[$commit->getPHID()])) {
unset($this->identifierMap[$name]);
}
}
}
}
private function buildJoinClause($conn_r) {
$joins = array();
$audit_request = new PhabricatorRepositoryAuditRequest();
if ($this->shouldJoinAudits()) {
$joins[] = qsprintf(
$conn_r,
'%Q %T audit ON commit.phid = audit.commitPHID',
($this->rowsMustHaveAudits() ? 'JOIN' : 'LEFT JOIN'),
$audit_request->getTableName());
}
if ($this->auditAwaitingUser) {
// Join the request table on the awaiting user's requests, so we can
// filter out package and project requests which the user has resigned
// from.
$joins[] = qsprintf(
$conn_r,
'LEFT JOIN %T awaiting ON audit.commitPHID = awaiting.commitPHID AND
awaiting.auditorPHID = %s',
$audit_request->getTableName(),
$this->auditAwaitingUser->getPHID());
}
if ($joins) {
return implode(' ', $joins);
} else {
return '';
}
}
private function buildGroupClause(AphrontDatabaseConnection $conn_r) {
$should_group = $this->shouldJoinAudits();
// TODO: Currently, the audit table is missing a unique key, so we may
// require a GROUP BY if we perform this join. See T1768. This can be
// removed once the table has the key.
if ($this->auditAwaitingUser) {
$should_group = true;
}
if ($should_group) {
return 'GROUP BY commit.id';
} else {
return '';
}
}
public function getQueryApplicationClass() {
return 'PhabricatorDiffusionApplication';
}
}
diff --git a/src/applications/doorkeeper/query/DoorkeeperExternalObjectQuery.php b/src/applications/doorkeeper/query/DoorkeeperExternalObjectQuery.php
index b67bc0e7a5..75ace905da 100644
--- a/src/applications/doorkeeper/query/DoorkeeperExternalObjectQuery.php
+++ b/src/applications/doorkeeper/query/DoorkeeperExternalObjectQuery.php
@@ -1,59 +1,59 @@
<?php
final class DoorkeeperExternalObjectQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
protected $phids;
protected $objectKeys;
public function withPHIDs(array $phids) {
$this->phids = $phids;
return $this;
}
public function withObjectKeys(array $keys) {
$this->objectKeys = $keys;
return $this;
}
- public function loadPage() {
+ protected function loadPage() {
$table = new DoorkeeperExternalObject();
$conn_r = $table->establishConnection('r');
$data = queryfx_all(
$conn_r,
'SELECT * FROM %T %Q %Q %Q',
$table->getTableName(),
$this->buildWhereClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
return $table->loadAllFromArray($data);
}
private function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();
if ($this->phids) {
$where[] = qsprintf(
$conn_r,
'phid IN (%Ls)',
$this->phids);
}
if ($this->objectKeys) {
$where[] = qsprintf(
$conn_r,
'objectKey IN (%Ls)',
$this->objectKeys);
}
$where[] = $this->buildPagingClause($conn_r);
return $this->formatWhereClause($where);
}
public function getQueryApplicationClass() {
return 'PhabricatorDoorkeeperApplication';
}
}
diff --git a/src/applications/drydock/query/DrydockBlueprintQuery.php b/src/applications/drydock/query/DrydockBlueprintQuery.php
index 72d9d9ada8..4afdb582c2 100644
--- a/src/applications/drydock/query/DrydockBlueprintQuery.php
+++ b/src/applications/drydock/query/DrydockBlueprintQuery.php
@@ -1,65 +1,65 @@
<?php
final class DrydockBlueprintQuery extends DrydockQuery {
private $ids;
private $phids;
public function withIDs(array $ids) {
$this->ids = $ids;
return $this;
}
public function withPHIDs(array $phids) {
$this->phids = $phids;
return $this;
}
- public function loadPage() {
+ protected function loadPage() {
$table = new DrydockBlueprint();
$conn_r = $table->establishConnection('r');
$data = queryfx_all(
$conn_r,
'SELECT blueprint.* FROM %T blueprint %Q %Q %Q',
$table->getTableName(),
$this->buildWhereClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
$blueprints = $table->loadAllFromArray($data);
$implementations =
DrydockBlueprintImplementation::getAllBlueprintImplementations();
foreach ($blueprints as $blueprint) {
if (array_key_exists($blueprint->getClassName(), $implementations)) {
$blueprint->attachImplementation(
$implementations[$blueprint->getClassName()]);
}
}
return $blueprints;
}
private function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();
if ($this->ids) {
$where[] = qsprintf(
$conn_r,
'id IN (%Ld)',
$this->ids);
}
if ($this->phids) {
$where[] = qsprintf(
$conn_r,
'phid IN (%Ls)',
$this->phids);
}
return $this->formatWhereClause($where);
}
}
diff --git a/src/applications/drydock/query/DrydockLeaseQuery.php b/src/applications/drydock/query/DrydockLeaseQuery.php
index 21e6319dda..028351bdae 100644
--- a/src/applications/drydock/query/DrydockLeaseQuery.php
+++ b/src/applications/drydock/query/DrydockLeaseQuery.php
@@ -1,108 +1,108 @@
<?php
final class DrydockLeaseQuery extends DrydockQuery {
private $ids;
private $phids;
private $resourceIDs;
private $statuses;
public function withIDs(array $ids) {
$this->ids = $ids;
return $this;
}
public function withPHIDs(array $phids) {
$this->phids = $phids;
return $this;
}
public function withResourceIDs(array $ids) {
$this->resourceIDs = $ids;
return $this;
}
public function withStatuses(array $statuses) {
$this->statuses = $statuses;
return $this;
}
- public function loadPage() {
+ protected function loadPage() {
$table = new DrydockLease();
$conn_r = $table->establishConnection('r');
$data = queryfx_all(
$conn_r,
'SELECT lease.* FROM %T lease %Q %Q %Q',
$table->getTableName(),
$this->buildWhereClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
return $table->loadAllFromArray($data);
}
- public function willFilterPage(array $leases) {
+ protected function willFilterPage(array $leases) {
$resource_ids = array_filter(mpull($leases, 'getResourceID'));
if ($resource_ids) {
$resources = id(new DrydockResourceQuery())
->setParentQuery($this)
->setViewer($this->getViewer())
->withIDs($resource_ids)
->execute();
} else {
$resources = array();
}
foreach ($leases as $key => $lease) {
$resource = null;
if ($lease->getResourceID()) {
$resource = idx($resources, $lease->getResourceID());
if (!$resource) {
unset($leases[$key]);
continue;
}
}
$lease->attachResource($resource);
}
return $leases;
}
private function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();
if ($this->resourceIDs) {
$where[] = qsprintf(
$conn_r,
'resourceID IN (%Ld)',
$this->resourceIDs);
}
if ($this->ids) {
$where[] = qsprintf(
$conn_r,
'id IN (%Ld)',
$this->ids);
}
if ($this->phids) {
$where[] = qsprintf(
$conn_r,
'phid IN (%Ls)',
$this->phids);
}
if ($this->statuses) {
$where[] = qsprintf(
$conn_r,
'status IN (%Ld)',
$this->statuses);
}
$where[] = $this->buildPagingClause($conn_r);
return $this->formatWhereClause($where);
}
}
diff --git a/src/applications/drydock/query/DrydockLogQuery.php b/src/applications/drydock/query/DrydockLogQuery.php
index 0488fb204a..83413d79c0 100644
--- a/src/applications/drydock/query/DrydockLogQuery.php
+++ b/src/applications/drydock/query/DrydockLogQuery.php
@@ -1,113 +1,113 @@
<?php
final class DrydockLogQuery extends DrydockQuery {
private $resourceIDs;
private $leaseIDs;
public function withResourceIDs(array $ids) {
$this->resourceIDs = $ids;
return $this;
}
public function withLeaseIDs(array $ids) {
$this->leaseIDs = $ids;
return $this;
}
- public function loadPage() {
+ protected function loadPage() {
$table = new DrydockLog();
$conn_r = $table->establishConnection('r');
$data = queryfx_all(
$conn_r,
'SELECT log.* FROM %T log %Q %Q %Q',
$table->getTableName(),
$this->buildWhereClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
return $table->loadAllFromArray($data);
}
- public function willFilterPage(array $logs) {
+ protected function willFilterPage(array $logs) {
$resource_ids = array_filter(mpull($logs, 'getResourceID'));
if ($resource_ids) {
$resources = id(new DrydockResourceQuery())
->setParentQuery($this)
->setViewer($this->getViewer())
->withIDs($resource_ids)
->execute();
} else {
$resources = array();
}
foreach ($logs as $key => $log) {
$resource = null;
if ($log->getResourceID()) {
$resource = idx($resources, $log->getResourceID());
if (!$resource) {
unset($logs[$key]);
continue;
}
}
$log->attachResource($resource);
}
$lease_ids = array_filter(mpull($logs, 'getLeaseID'));
if ($lease_ids) {
$leases = id(new DrydockLeaseQuery())
->setParentQuery($this)
->setViewer($this->getViewer())
->withIDs($lease_ids)
->execute();
} else {
$leases = array();
}
foreach ($logs as $key => $log) {
$lease = null;
if ($log->getLeaseID()) {
$lease = idx($leases, $log->getLeaseID());
if (!$lease) {
unset($logs[$key]);
continue;
}
}
$log->attachLease($lease);
}
// These logs are meaningless and their policies aren't computable. They
// shouldn't exist, but throw them away if they do.
foreach ($logs as $key => $log) {
if (!$log->getResource() && !$log->getLease()) {
unset($logs[$key]);
}
}
return $logs;
}
private function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();
if ($this->resourceIDs) {
$where[] = qsprintf(
$conn_r,
'resourceID IN (%Ld)',
$this->resourceIDs);
}
if ($this->leaseIDs) {
$where[] = qsprintf(
$conn_r,
'leaseID IN (%Ld)',
$this->leaseIDs);
}
$where[] = $this->buildPagingClause($conn_r);
return $this->formatWhereClause($where);
}
}
diff --git a/src/applications/drydock/query/DrydockResourceQuery.php b/src/applications/drydock/query/DrydockResourceQuery.php
index 870a7dd653..468af91db4 100644
--- a/src/applications/drydock/query/DrydockResourceQuery.php
+++ b/src/applications/drydock/query/DrydockResourceQuery.php
@@ -1,96 +1,96 @@
<?php
final class DrydockResourceQuery extends DrydockQuery {
private $ids;
private $phids;
private $statuses;
private $types;
private $blueprintPHIDs;
public function withIDs(array $ids) {
$this->ids = $ids;
return $this;
}
public function withPHIDs(array $phids) {
$this->phids = $phids;
return $this;
}
public function withTypes(array $types) {
$this->types = $types;
return $this;
}
public function withStatuses(array $statuses) {
$this->statuses = $statuses;
return $this;
}
public function withBlueprintPHIDs(array $blueprint_phids) {
$this->blueprintPHIDs = $blueprint_phids;
return $this;
}
- public function loadPage() {
+ protected function loadPage() {
$table = new DrydockResource();
$conn_r = $table->establishConnection('r');
$data = queryfx_all(
$conn_r,
'SELECT resource.* FROM %T resource %Q %Q %Q',
$table->getTableName(),
$this->buildWhereClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
$resources = $table->loadAllFromArray($data);
return $resources;
}
private function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();
if ($this->ids) {
$where[] = qsprintf(
$conn_r,
'id IN (%Ld)',
$this->ids);
}
if ($this->phids) {
$where[] = qsprintf(
$conn_r,
'phid IN (%Ls)',
$this->phids);
}
if ($this->types) {
$where[] = qsprintf(
$conn_r,
'type IN (%Ls)',
$this->types);
}
if ($this->statuses) {
$where[] = qsprintf(
$conn_r,
'status IN (%Ls)',
$this->statuses);
}
if ($this->blueprintPHIDs) {
$where[] = qsprintf(
$conn_r,
'blueprintPHID IN (%Ls)',
$this->blueprintPHIDs);
}
$where[] = $this->buildPagingClause($conn_r);
return $this->formatWhereClause($where);
}
}
diff --git a/src/applications/flag/query/PhabricatorFlagQuery.php b/src/applications/flag/query/PhabricatorFlagQuery.php
index d7950f3008..910ed7dfa9 100644
--- a/src/applications/flag/query/PhabricatorFlagQuery.php
+++ b/src/applications/flag/query/PhabricatorFlagQuery.php
@@ -1,165 +1,165 @@
<?php
final class PhabricatorFlagQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
const GROUP_COLOR = 'color';
const GROUP_NONE = 'none';
private $ownerPHIDs;
private $types;
private $objectPHIDs;
private $colors;
private $groupBy = self::GROUP_NONE;
private $needHandles;
private $needObjects;
public function withOwnerPHIDs(array $owner_phids) {
$this->ownerPHIDs = $owner_phids;
return $this;
}
public function withTypes(array $types) {
$this->types = $types;
return $this;
}
public function withObjectPHIDs(array $object_phids) {
$this->objectPHIDs = $object_phids;
return $this;
}
public function withColors(array $colors) {
$this->colors = $colors;
return $this;
}
/**
* NOTE: this is done in PHP and not in MySQL, which means its inappropriate
* for large datasets. Pragmatically, this is fine for user flags which are
* typically well under 100 flags per user.
*/
public function setGroupBy($group) {
$this->groupBy = $group;
return $this;
}
public function needHandles($need) {
$this->needHandles = $need;
return $this;
}
public function needObjects($need) {
$this->needObjects = $need;
return $this;
}
public static function loadUserFlag(PhabricatorUser $user, $object_phid) {
// Specifying the type in the query allows us to use a key.
return id(new PhabricatorFlagQuery())
->setViewer($user)
->withOwnerPHIDs(array($user->getPHID()))
->withTypes(array(phid_get_type($object_phid)))
->withObjectPHIDs(array($object_phid))
->executeOne();
}
- public function loadPage() {
+ protected function loadPage() {
$table = new PhabricatorFlag();
$conn_r = $table->establishConnection('r');
$data = queryfx_all(
$conn_r,
'SELECT * FROM %T flag %Q %Q %Q',
$table->getTableName(),
$this->buildWhereClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
return $table->loadAllFromArray($data);
}
- public function willFilterPage(array $flags) {
+ protected function willFilterPage(array $flags) {
if ($this->needObjects) {
$objects = id(new PhabricatorObjectQuery())
->setViewer($this->getViewer())
->withPHIDs(mpull($flags, 'getObjectPHID'))
->execute();
$objects = mpull($objects, null, 'getPHID');
foreach ($flags as $key => $flag) {
$object = idx($objects, $flag->getObjectPHID());
if ($object) {
$flags[$key]->attachObject($object);
} else {
unset($flags[$key]);
}
}
}
if ($this->needHandles) {
$handles = id(new PhabricatorHandleQuery())
->setViewer($this->getViewer())
->withPHIDs(mpull($flags, 'getObjectPHID'))
->execute();
foreach ($flags as $flag) {
$flag->attachHandle($handles[$flag->getObjectPHID()]);
}
}
switch ($this->groupBy) {
case self::GROUP_COLOR:
$flags = msort($flags, 'getColor');
break;
case self::GROUP_NONE:
break;
default:
throw new Exception("Unknown groupBy parameter: $this->groupBy");
break;
}
return $flags;
}
private function buildWhereClause($conn_r) {
$where = array();
if ($this->ownerPHIDs) {
$where[] = qsprintf(
$conn_r,
'flag.ownerPHID IN (%Ls)',
$this->ownerPHIDs);
}
if ($this->types) {
$where[] = qsprintf(
$conn_r,
'flag.type IN (%Ls)',
$this->types);
}
if ($this->objectPHIDs) {
$where[] = qsprintf(
$conn_r,
'flag.objectPHID IN (%Ls)',
$this->objectPHIDs);
}
if ($this->colors) {
$where[] = qsprintf(
$conn_r,
'flag.color IN (%Ld)',
$this->colors);
}
$where[] = $this->buildPagingClause($conn_r);
return $this->formatWhereClause($where);
}
public function getQueryApplicationClass() {
return 'PhabricatorFlagsApplication';
}
}
diff --git a/src/applications/herald/query/HeraldRuleQuery.php b/src/applications/herald/query/HeraldRuleQuery.php
index 512557399d..6e88dc40a0 100644
--- a/src/applications/herald/query/HeraldRuleQuery.php
+++ b/src/applications/herald/query/HeraldRuleQuery.php
@@ -1,276 +1,276 @@
<?php
final class HeraldRuleQuery extends PhabricatorCursorPagedPolicyAwareQuery {
private $ids;
private $phids;
private $authorPHIDs;
private $ruleTypes;
private $contentTypes;
private $disabled;
private $triggerObjectPHIDs;
private $needConditionsAndActions;
private $needAppliedToPHIDs;
private $needValidateAuthors;
public function withIDs(array $ids) {
$this->ids = $ids;
return $this;
}
public function withPHIDs(array $phids) {
$this->phids = $phids;
return $this;
}
public function withAuthorPHIDs(array $author_phids) {
$this->authorPHIDs = $author_phids;
return $this;
}
public function withRuleTypes(array $types) {
$this->ruleTypes = $types;
return $this;
}
public function withContentTypes(array $types) {
$this->contentTypes = $types;
return $this;
}
public function withExecutableRules($executable) {
$this->executable = $executable;
return $this;
}
public function withDisabled($disabled) {
$this->disabled = $disabled;
return $this;
}
public function withTriggerObjectPHIDs(array $phids) {
$this->triggerObjectPHIDs = $phids;
return $this;
}
public function needConditionsAndActions($need) {
$this->needConditionsAndActions = $need;
return $this;
}
public function needAppliedToPHIDs(array $phids) {
$this->needAppliedToPHIDs = $phids;
return $this;
}
public function needValidateAuthors($need) {
$this->needValidateAuthors = $need;
return $this;
}
- public function loadPage() {
+ protected function loadPage() {
$table = new HeraldRule();
$conn_r = $table->establishConnection('r');
$data = queryfx_all(
$conn_r,
'SELECT rule.* FROM %T rule %Q %Q %Q',
$table->getTableName(),
$this->buildWhereClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
return $table->loadAllFromArray($data);
}
- public function willFilterPage(array $rules) {
+ protected function willFilterPage(array $rules) {
$rule_ids = mpull($rules, 'getID');
// Filter out any rules that have invalid adapters, or have adapters the
// viewer isn't permitted to see or use (for example, Differential rules
// if the user can't use Differential or Differential is not installed).
$types = HeraldAdapter::getEnabledAdapterMap($this->getViewer());
foreach ($rules as $key => $rule) {
if (empty($types[$rule->getContentType()])) {
$this->didRejectResult($rule);
unset($rules[$key]);
}
}
if ($this->needValidateAuthors) {
$this->validateRuleAuthors($rules);
}
if ($this->needConditionsAndActions) {
$conditions = id(new HeraldCondition())->loadAllWhere(
'ruleID IN (%Ld)',
$rule_ids);
$conditions = mgroup($conditions, 'getRuleID');
$actions = id(new HeraldAction())->loadAllWhere(
'ruleID IN (%Ld)',
$rule_ids);
$actions = mgroup($actions, 'getRuleID');
foreach ($rules as $rule) {
$rule->attachActions(idx($actions, $rule->getID(), array()));
$rule->attachConditions(idx($conditions, $rule->getID(), array()));
}
}
if ($this->needAppliedToPHIDs) {
$conn_r = id(new HeraldRule())->establishConnection('r');
$applied = queryfx_all(
$conn_r,
'SELECT * FROM %T WHERE ruleID IN (%Ld) AND phid IN (%Ls)',
HeraldRule::TABLE_RULE_APPLIED,
$rule_ids,
$this->needAppliedToPHIDs);
$map = array();
foreach ($applied as $row) {
$map[$row['ruleID']][$row['phid']] = true;
}
foreach ($rules as $rule) {
foreach ($this->needAppliedToPHIDs as $phid) {
$rule->setRuleApplied(
$phid,
isset($map[$rule->getID()][$phid]));
}
}
}
$object_phids = array();
foreach ($rules as $rule) {
if ($rule->isObjectRule()) {
$object_phids[] = $rule->getTriggerObjectPHID();
}
}
if ($object_phids) {
$objects = id(new PhabricatorObjectQuery())
->setParentQuery($this)
->setViewer($this->getViewer())
->withPHIDs($object_phids)
->execute();
$objects = mpull($objects, null, 'getPHID');
} else {
$objects = array();
}
foreach ($rules as $key => $rule) {
if ($rule->isObjectRule()) {
$object = idx($objects, $rule->getTriggerObjectPHID());
if (!$object) {
unset($rules[$key]);
continue;
}
$rule->attachTriggerObject($object);
}
}
return $rules;
}
private function buildWhereClause($conn_r) {
$where = array();
if ($this->ids) {
$where[] = qsprintf(
$conn_r,
'rule.id IN (%Ld)',
$this->ids);
}
if ($this->phids) {
$where[] = qsprintf(
$conn_r,
'rule.phid IN (%Ls)',
$this->phids);
}
if ($this->authorPHIDs) {
$where[] = qsprintf(
$conn_r,
'rule.authorPHID IN (%Ls)',
$this->authorPHIDs);
}
if ($this->ruleTypes) {
$where[] = qsprintf(
$conn_r,
'rule.ruleType IN (%Ls)',
$this->ruleTypes);
}
if ($this->contentTypes) {
$where[] = qsprintf(
$conn_r,
'rule.contentType IN (%Ls)',
$this->contentTypes);
}
if ($this->disabled !== null) {
$where[] = qsprintf(
$conn_r,
'rule.isDisabled = %d',
(int)$this->disabled);
}
if ($this->triggerObjectPHIDs) {
$where[] = qsprintf(
$conn_r,
'rule.triggerObjectPHID IN (%Ls)',
$this->triggerObjectPHIDs);
}
$where[] = $this->buildPagingClause($conn_r);
return $this->formatWhereClause($where);
}
private function validateRuleAuthors(array $rules) {
// "Global" and "Object" rules always have valid authors.
foreach ($rules as $key => $rule) {
if ($rule->isGlobalRule() || $rule->isObjectRule()) {
$rule->attachValidAuthor(true);
unset($rules[$key]);
continue;
}
}
if (!$rules) {
return;
}
// For personal rules, the author needs to exist and not be disabled.
$user_phids = mpull($rules, 'getAuthorPHID');
$users = id(new PhabricatorPeopleQuery())
->setViewer($this->getViewer())
->withPHIDs($user_phids)
->execute();
$users = mpull($users, null, 'getPHID');
foreach ($rules as $key => $rule) {
$author_phid = $rule->getAuthorPHID();
if (empty($users[$author_phid])) {
$rule->attachValidAuthor(false);
continue;
}
if (!$users[$author_phid]->isUserActivated()) {
$rule->attachValidAuthor(false);
continue;
}
$rule->attachValidAuthor(true);
$rule->attachAuthor($users[$author_phid]);
}
}
public function getQueryApplicationClass() {
return 'PhabricatorHeraldApplication';
}
}
diff --git a/src/applications/herald/query/HeraldTranscriptQuery.php b/src/applications/herald/query/HeraldTranscriptQuery.php
index 2f4a6ff954..b76b657a7f 100644
--- a/src/applications/herald/query/HeraldTranscriptQuery.php
+++ b/src/applications/herald/query/HeraldTranscriptQuery.php
@@ -1,114 +1,114 @@
<?php
final class HeraldTranscriptQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
private $ids;
private $objectPHIDs;
private $needPartialRecords;
public function withIDs(array $ids) {
$this->ids = $ids;
return $this;
}
public function withObjectPHIDs(array $phids) {
$this->objectPHIDs = $phids;
return $this;
}
public function needPartialRecords($need_partial) {
$this->needPartialRecords = $need_partial;
return $this;
}
- public function loadPage() {
+ protected function loadPage() {
$transcript = new HeraldTranscript();
$conn_r = $transcript->establishConnection('r');
// NOTE: Transcripts include a potentially enormous amount of serialized
// data, so we're loading only some of the fields here if the caller asked
// for partial records.
if ($this->needPartialRecords) {
$fields = implode(
', ',
array(
'id',
'phid',
'objectPHID',
'time',
'duration',
'dryRun',
'host',
));
} else {
$fields = '*';
}
$rows = queryfx_all(
$conn_r,
'SELECT %Q FROM %T t %Q %Q %Q',
$fields,
$transcript->getTableName(),
$this->buildWhereClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
$transcripts = $transcript->loadAllFromArray($rows);
if ($this->needPartialRecords) {
// Make sure nothing tries to write these; they aren't complete.
foreach ($transcripts as $transcript) {
$transcript->makeEphemeral();
}
}
return $transcripts;
}
- public function willFilterPage(array $transcripts) {
+ protected function willFilterPage(array $transcripts) {
$phids = mpull($transcripts, 'getObjectPHID');
$objects = id(new PhabricatorObjectQuery())
->setViewer($this->getViewer())
->withPHIDs($phids)
->execute();
foreach ($transcripts as $key => $transcript) {
if (empty($objects[$transcript->getObjectPHID()])) {
$this->didRejectResult($transcript);
unset($transcripts[$key]);
}
}
return $transcripts;
}
public function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();
if ($this->ids) {
$where[] = qsprintf(
$conn_r,
'id IN (%Ld)',
$this->ids);
}
if ($this->objectPHIDs) {
$where[] = qsprintf(
$conn_r,
'objectPHID in (%Ls)',
$this->objectPHIDs);
}
$where[] = $this->buildPagingClause($conn_r);
return $this->formatWhereClause($where);
}
public function getQueryApplicationClass() {
return 'PhabricatorHeraldApplication';
}
}
diff --git a/src/applications/mailinglists/query/PhabricatorMailingListQuery.php b/src/applications/mailinglists/query/PhabricatorMailingListQuery.php
index 81be315f92..44f54edbda 100644
--- a/src/applications/mailinglists/query/PhabricatorMailingListQuery.php
+++ b/src/applications/mailinglists/query/PhabricatorMailingListQuery.php
@@ -1,86 +1,86 @@
<?php
final class PhabricatorMailingListQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
private $phids;
private $ids;
private $emails;
private $names;
public function withIDs($ids) {
$this->ids = $ids;
return $this;
}
public function withPHIDs($phids) {
$this->phids = $phids;
return $this;
}
public function withEmails(array $emails) {
$this->emails = $emails;
return $this;
}
public function withNames(array $names) {
$this->names = $names;
return $this;
}
- public function loadPage() {
+ protected function loadPage() {
$table = new PhabricatorMetaMTAMailingList();
$conn_r = $table->establishConnection('r');
$data = queryfx_all(
$conn_r,
'SELECT * FROM %T %Q %Q %Q',
$table->getTableName(),
$this->buildWhereClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
return $table->loadAllFromArray($data);
}
private function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();
if ($this->ids) {
$where[] = qsprintf(
$conn_r,
'id IN (%Ld)',
$this->ids);
}
if ($this->phids) {
$where[] = qsprintf(
$conn_r,
'phid IN (%Ls)',
$this->phids);
}
if ($this->names) {
$where[] = qsprintf(
$conn_r,
'name IN (%Ls)',
$this->names);
}
if ($this->emails) {
$where[] = qsprintf(
$conn_r,
'email IN (%Ls)',
$this->emails);
}
$where[] = $this->buildPagingClause($conn_r);
return $this->formatWhereClause($where);
}
public function getQueryApplicationClass() {
return 'PhabricatorMailingListsApplication';
}
}
diff --git a/src/applications/maniphest/query/ManiphestTaskQuery.php b/src/applications/maniphest/query/ManiphestTaskQuery.php
index ba22f024c4..37db3444e3 100644
--- a/src/applications/maniphest/query/ManiphestTaskQuery.php
+++ b/src/applications/maniphest/query/ManiphestTaskQuery.php
@@ -1,1097 +1,1097 @@
<?php
/**
* Query tasks by specific criteria. This class uses the higher-performance
* but less-general Maniphest indexes to satisfy queries.
*/
final class ManiphestTaskQuery extends PhabricatorCursorPagedPolicyAwareQuery {
private $taskIDs = array();
private $taskPHIDs = array();
private $authorPHIDs = array();
private $ownerPHIDs = array();
private $includeUnowned = null;
private $projectPHIDs = array();
private $xprojectPHIDs = array();
private $subscriberPHIDs = array();
private $anyProjectPHIDs = array();
private $anyUserProjectPHIDs = array();
private $includeNoProject = null;
private $dateCreatedAfter;
private $dateCreatedBefore;
private $dateModifiedAfter;
private $dateModifiedBefore;
private $fullTextSearch = '';
private $status = 'status-any';
const STATUS_ANY = 'status-any';
const STATUS_OPEN = 'status-open';
const STATUS_CLOSED = 'status-closed';
const STATUS_RESOLVED = 'status-resolved';
const STATUS_WONTFIX = 'status-wontfix';
const STATUS_INVALID = 'status-invalid';
const STATUS_SPITE = 'status-spite';
const STATUS_DUPLICATE = 'status-duplicate';
private $statuses;
private $priorities;
private $groupBy = 'group-none';
const GROUP_NONE = 'group-none';
const GROUP_PRIORITY = 'group-priority';
const GROUP_OWNER = 'group-owner';
const GROUP_STATUS = 'group-status';
const GROUP_PROJECT = 'group-project';
private $orderBy = 'order-modified';
const ORDER_PRIORITY = 'order-priority';
const ORDER_CREATED = 'order-created';
const ORDER_MODIFIED = 'order-modified';
const ORDER_TITLE = 'order-title';
private $needSubscriberPHIDs;
private $needProjectPHIDs;
private $blockingTasks;
private $blockedTasks;
const DEFAULT_PAGE_SIZE = 1000;
public function withAuthors(array $authors) {
$this->authorPHIDs = $authors;
return $this;
}
public function withIDs(array $ids) {
$this->taskIDs = $ids;
return $this;
}
public function withPHIDs(array $phids) {
$this->taskPHIDs = $phids;
return $this;
}
public function withOwners(array $owners) {
$this->includeUnowned = false;
foreach ($owners as $k => $phid) {
if ($phid == ManiphestTaskOwner::OWNER_UP_FOR_GRABS || $phid === null) {
$this->includeUnowned = true;
unset($owners[$k]);
break;
}
}
$this->ownerPHIDs = $owners;
return $this;
}
public function withAllProjects(array $projects) {
$this->includeNoProject = false;
foreach ($projects as $k => $phid) {
if ($phid == ManiphestTaskOwner::PROJECT_NO_PROJECT) {
$this->includeNoProject = true;
unset($projects[$k]);
}
}
$this->projectPHIDs = $projects;
return $this;
}
/**
* Add an additional "all projects" constraint to existing filters.
*
* This is used by boards to supplement queries.
*
* @param list<phid> List of project PHIDs to add to any existing constraint.
* @return this
*/
public function addWithAllProjects(array $projects) {
if ($this->projectPHIDs === null) {
$this->projectPHIDs = array();
}
return $this->withAllProjects(array_merge($this->projectPHIDs, $projects));
}
public function withoutProjects(array $projects) {
$this->xprojectPHIDs = $projects;
return $this;
}
public function withStatus($status) {
$this->status = $status;
return $this;
}
public function withStatuses(array $statuses) {
$this->statuses = $statuses;
return $this;
}
public function withPriorities(array $priorities) {
$this->priorities = $priorities;
return $this;
}
public function withSubscribers(array $subscribers) {
$this->subscriberPHIDs = $subscribers;
return $this;
}
public function withFullTextSearch($fulltext_search) {
$this->fullTextSearch = $fulltext_search;
return $this;
}
public function setGroupBy($group) {
$this->groupBy = $group;
return $this;
}
public function setOrderBy($order) {
$this->orderBy = $order;
return $this;
}
public function withAnyProjects(array $projects) {
$this->anyProjectPHIDs = $projects;
return $this;
}
public function withAnyUserProjects(array $users) {
$this->anyUserProjectPHIDs = $users;
return $this;
}
/**
* True returns tasks that are blocking other tasks only.
* False returns tasks that are not blocking other tasks only.
* Null returns tasks regardless of blocking status.
*/
public function withBlockingTasks($mode) {
$this->blockingTasks = $mode;
return $this;
}
public function shouldJoinBlockingTasks() {
return $this->blockingTasks !== null;
}
/**
* True returns tasks that are blocked by other tasks only.
* False returns tasks that are not blocked by other tasks only.
* Null returns tasks regardless of blocked by status.
*/
public function withBlockedTasks($mode) {
$this->blockedTasks = $mode;
return $this;
}
public function shouldJoinBlockedTasks() {
return $this->blockedTasks !== null;
}
public function withDateCreatedBefore($date_created_before) {
$this->dateCreatedBefore = $date_created_before;
return $this;
}
public function withDateCreatedAfter($date_created_after) {
$this->dateCreatedAfter = $date_created_after;
return $this;
}
public function withDateModifiedBefore($date_modified_before) {
$this->dateModifiedBefore = $date_modified_before;
return $this;
}
public function withDateModifiedAfter($date_modified_after) {
$this->dateModifiedAfter = $date_modified_after;
return $this;
}
public function needSubscriberPHIDs($bool) {
$this->needSubscriberPHIDs = $bool;
return $this;
}
public function needProjectPHIDs($bool) {
$this->needProjectPHIDs = $bool;
return $this;
}
- public function loadPage() {
+ protected function loadPage() {
// TODO: (T603) It is possible for a user to find the PHID of a project
// they can't see, then query for tasks in that project and deduce the
// identity of unknown/invisible projects. Before we allow the user to
// execute a project-based PHID query, we should verify that they
// can see the project.
$task_dao = new ManiphestTask();
$conn = $task_dao->establishConnection('r');
$where = array();
$where[] = $this->buildTaskIDsWhereClause($conn);
$where[] = $this->buildTaskPHIDsWhereClause($conn);
$where[] = $this->buildStatusWhereClause($conn);
$where[] = $this->buildStatusesWhereClause($conn);
$where[] = $this->buildPrioritiesWhereClause($conn);
$where[] = $this->buildDependenciesWhereClause($conn);
$where[] = $this->buildAuthorWhereClause($conn);
$where[] = $this->buildOwnerWhereClause($conn);
$where[] = $this->buildProjectWhereClause($conn);
$where[] = $this->buildAnyProjectWhereClause($conn);
$where[] = $this->buildAnyUserProjectWhereClause($conn);
$where[] = $this->buildXProjectWhereClause($conn);
$where[] = $this->buildFullTextWhereClause($conn);
if ($this->dateCreatedAfter) {
$where[] = qsprintf(
$conn,
'task.dateCreated >= %d',
$this->dateCreatedAfter);
}
if ($this->dateCreatedBefore) {
$where[] = qsprintf(
$conn,
'task.dateCreated <= %d',
$this->dateCreatedBefore);
}
if ($this->dateModifiedAfter) {
$where[] = qsprintf(
$conn,
'task.dateModified >= %d',
$this->dateModifiedAfter);
}
if ($this->dateModifiedBefore) {
$where[] = qsprintf(
$conn,
'task.dateModified <= %d',
$this->dateModifiedBefore);
}
$where[] = $this->buildPagingClause($conn);
$where = $this->formatWhereClause($where);
$having = '';
$count = '';
if (count($this->projectPHIDs) > 1) {
// We want to treat the query as an intersection query, not a union
// query. We sum the project count and require it be the same as the
// number of projects we're searching for.
$count = ', COUNT(project.dst) projectCount';
$having = qsprintf(
$conn,
'HAVING projectCount = %d',
count($this->projectPHIDs));
}
$order = $this->buildCustomOrderClause($conn);
// TODO: Clean up this nonstandardness.
if (!$this->getLimit()) {
$this->setLimit(self::DEFAULT_PAGE_SIZE);
}
$group_column = '';
switch ($this->groupBy) {
case self::GROUP_PROJECT:
$group_column = qsprintf(
$conn,
', projectGroupName.indexedObjectPHID projectGroupPHID');
break;
}
$rows = queryfx_all(
$conn,
'SELECT task.* %Q %Q FROM %T task %Q %Q %Q %Q %Q %Q',
$count,
$group_column,
$task_dao->getTableName(),
$this->buildJoinsClause($conn),
$where,
$this->buildGroupClause($conn),
$having,
$order,
$this->buildLimitClause($conn));
switch ($this->groupBy) {
case self::GROUP_PROJECT:
$data = ipull($rows, null, 'id');
break;
default:
$data = $rows;
break;
}
$tasks = $task_dao->loadAllFromArray($data);
switch ($this->groupBy) {
case self::GROUP_PROJECT:
$results = array();
foreach ($rows as $row) {
$task = clone $tasks[$row['id']];
$task->attachGroupByProjectPHID($row['projectGroupPHID']);
$results[] = $task;
}
$tasks = $results;
break;
}
return $tasks;
}
protected function willFilterPage(array $tasks) {
if ($this->groupBy == self::GROUP_PROJECT) {
// We should only return project groups which the user can actually see.
$project_phids = mpull($tasks, 'getGroupByProjectPHID');
$projects = id(new PhabricatorProjectQuery())
->setViewer($this->getViewer())
->withPHIDs($project_phids)
->execute();
$projects = mpull($projects, null, 'getPHID');
foreach ($tasks as $key => $task) {
if (!$task->getGroupByProjectPHID()) {
// This task is either not in any projects, or only in projects
// which we're ignoring because they're being queried for explicitly.
continue;
}
if (empty($projects[$task->getGroupByProjectPHID()])) {
unset($tasks[$key]);
}
}
}
return $tasks;
}
protected function didFilterPage(array $tasks) {
$phids = mpull($tasks, 'getPHID');
if ($this->needProjectPHIDs) {
$edge_query = id(new PhabricatorEdgeQuery())
->withSourcePHIDs($phids)
->withEdgeTypes(
array(
PhabricatorProjectObjectHasProjectEdgeType::EDGECONST,
));
$edge_query->execute();
foreach ($tasks as $task) {
$project_phids = $edge_query->getDestinationPHIDs(
array($task->getPHID()));
$task->attachProjectPHIDs($project_phids);
}
}
if ($this->needSubscriberPHIDs) {
$subscriber_sets = id(new PhabricatorSubscribersQuery())
->withObjectPHIDs($phids)
->execute();
foreach ($tasks as $task) {
$subscribers = idx($subscriber_sets, $task->getPHID(), array());
$task->attachSubscriberPHIDs($subscribers);
}
}
return $tasks;
}
private function buildTaskIDsWhereClause(AphrontDatabaseConnection $conn) {
if (!$this->taskIDs) {
return null;
}
return qsprintf(
$conn,
'id in (%Ld)',
$this->taskIDs);
}
private function buildTaskPHIDsWhereClause(AphrontDatabaseConnection $conn) {
if (!$this->taskPHIDs) {
return null;
}
return qsprintf(
$conn,
'phid in (%Ls)',
$this->taskPHIDs);
}
private function buildStatusWhereClause(AphrontDatabaseConnection $conn) {
static $map = array(
self::STATUS_RESOLVED => ManiphestTaskStatus::STATUS_CLOSED_RESOLVED,
self::STATUS_WONTFIX => ManiphestTaskStatus::STATUS_CLOSED_WONTFIX,
self::STATUS_INVALID => ManiphestTaskStatus::STATUS_CLOSED_INVALID,
self::STATUS_SPITE => ManiphestTaskStatus::STATUS_CLOSED_SPITE,
self::STATUS_DUPLICATE => ManiphestTaskStatus::STATUS_CLOSED_DUPLICATE,
);
switch ($this->status) {
case self::STATUS_ANY:
return null;
case self::STATUS_OPEN:
return qsprintf(
$conn,
'status IN (%Ls)',
ManiphestTaskStatus::getOpenStatusConstants());
case self::STATUS_CLOSED:
return qsprintf(
$conn,
'status IN (%Ls)',
ManiphestTaskStatus::getClosedStatusConstants());
default:
$constant = idx($map, $this->status);
if (!$constant) {
throw new Exception("Unknown status query '{$this->status}'!");
}
return qsprintf(
$conn,
'status = %s',
$constant);
}
}
private function buildStatusesWhereClause(AphrontDatabaseConnection $conn) {
if ($this->statuses) {
return qsprintf(
$conn,
'status IN (%Ls)',
$this->statuses);
}
return null;
}
private function buildPrioritiesWhereClause(AphrontDatabaseConnection $conn) {
if ($this->priorities) {
return qsprintf(
$conn,
'priority IN (%Ld)',
$this->priorities);
}
return null;
}
private function buildAuthorWhereClause(AphrontDatabaseConnection $conn) {
if (!$this->authorPHIDs) {
return null;
}
return qsprintf(
$conn,
'authorPHID in (%Ls)',
$this->authorPHIDs);
}
private function buildOwnerWhereClause(AphrontDatabaseConnection $conn) {
if (!$this->ownerPHIDs) {
if ($this->includeUnowned === null) {
return null;
} else if ($this->includeUnowned) {
return qsprintf(
$conn,
'ownerPHID IS NULL');
} else {
return qsprintf(
$conn,
'ownerPHID IS NOT NULL');
}
}
if ($this->includeUnowned) {
return qsprintf(
$conn,
'ownerPHID IN (%Ls) OR ownerPHID IS NULL',
$this->ownerPHIDs);
} else {
return qsprintf(
$conn,
'ownerPHID IN (%Ls)',
$this->ownerPHIDs);
}
}
private function buildFullTextWhereClause(AphrontDatabaseConnection $conn) {
if (!strlen($this->fullTextSearch)) {
return null;
}
// In doing a fulltext search, we first find all the PHIDs that match the
// fulltext search, and then use that to limit the rest of the search
$fulltext_query = id(new PhabricatorSavedQuery())
->setEngineClassName('PhabricatorSearchApplicationSearchEngine')
->setParameter('query', $this->fullTextSearch);
// NOTE: Setting this to something larger than 2^53 will raise errors in
// ElasticSearch, and billions of results won't fit in memory anyway.
$fulltext_query->setParameter('limit', 100000);
$fulltext_query->setParameter('type', ManiphestTaskPHIDType::TYPECONST);
$engine = PhabricatorSearchEngineSelector::newSelector()->newEngine();
$fulltext_results = $engine->executeSearch($fulltext_query);
if (empty($fulltext_results)) {
$fulltext_results = array(null);
}
return qsprintf(
$conn,
'phid IN (%Ls)',
$fulltext_results);
}
private function buildDependenciesWhereClause(
AphrontDatabaseConnection $conn) {
if (!$this->shouldJoinBlockedTasks() &&
!$this->shouldJoinBlockingTasks()) {
return null;
}
$parts = array();
if ($this->blockingTasks === true) {
$parts[] = qsprintf(
$conn,
'blocking.dst IS NOT NULL');
} else if ($this->blockingTasks === false) {
$parts[] = qsprintf(
$conn,
'blocking.dst IS NULL');
}
if ($this->blockedTasks === true) {
$parts[] = qsprintf(
$conn,
'blocked.dst IS NOT NULL');
} else if ($this->blockedTasks === false) {
$parts[] = qsprintf(
$conn,
'blocked.dst IS NULL');
}
return '('.implode(') OR (', $parts).')';
}
private function buildProjectWhereClause(AphrontDatabaseConnection $conn) {
if (!$this->projectPHIDs && !$this->includeNoProject) {
return null;
}
$parts = array();
if ($this->projectPHIDs) {
$parts[] = qsprintf(
$conn,
'project.dst in (%Ls)',
$this->projectPHIDs);
}
if ($this->includeNoProject) {
$parts[] = qsprintf(
$conn,
'project.dst IS NULL');
}
return '('.implode(') OR (', $parts).')';
}
private function buildAnyProjectWhereClause(AphrontDatabaseConnection $conn) {
if (!$this->anyProjectPHIDs) {
return null;
}
return qsprintf(
$conn,
'anyproject.dst IN (%Ls)',
$this->anyProjectPHIDs);
}
private function buildAnyUserProjectWhereClause(
AphrontDatabaseConnection $conn) {
if (!$this->anyUserProjectPHIDs) {
return null;
}
$projects = id(new PhabricatorProjectQuery())
->setViewer($this->getViewer())
->withMemberPHIDs($this->anyUserProjectPHIDs)
->execute();
$any_user_project_phids = mpull($projects, 'getPHID');
if (!$any_user_project_phids) {
throw new PhabricatorEmptyQueryException();
}
return qsprintf(
$conn,
'anyproject.dst IN (%Ls)',
$any_user_project_phids);
}
private function buildXProjectWhereClause(AphrontDatabaseConnection $conn) {
if (!$this->xprojectPHIDs) {
return null;
}
return qsprintf(
$conn,
'xproject.dst IS NULL');
}
private function buildCustomOrderClause(AphrontDatabaseConnection $conn) {
$reverse = ($this->getBeforeID() xor $this->getReversePaging());
$order = array();
switch ($this->groupBy) {
case self::GROUP_NONE:
break;
case self::GROUP_PRIORITY:
$order[] = 'priority';
break;
case self::GROUP_OWNER:
$order[] = 'ownerOrdering';
break;
case self::GROUP_STATUS:
$order[] = 'status';
break;
case self::GROUP_PROJECT:
$order[] = '<group.project>';
break;
default:
throw new Exception("Unknown group query '{$this->groupBy}'!");
}
$app_order = $this->buildApplicationSearchOrders($conn, $reverse);
if (!$app_order) {
switch ($this->orderBy) {
case self::ORDER_PRIORITY:
$order[] = 'priority';
$order[] = 'subpriority';
$order[] = 'dateModified';
break;
case self::ORDER_CREATED:
$order[] = 'id';
break;
case self::ORDER_MODIFIED:
$order[] = 'dateModified';
break;
case self::ORDER_TITLE:
$order[] = 'title';
break;
default:
throw new Exception("Unknown order query '{$this->orderBy}'!");
}
}
$order = array_unique($order);
if (empty($order) && empty($app_order)) {
return null;
}
foreach ($order as $k => $column) {
switch ($column) {
case 'subpriority':
case 'ownerOrdering':
case 'title':
if ($reverse) {
$order[$k] = "task.{$column} DESC";
} else {
$order[$k] = "task.{$column} ASC";
}
break;
case '<group.project>':
// Put "No Project" at the end of the list.
if ($reverse) {
$order[$k] =
'projectGroupName.indexedObjectName IS NULL DESC, '.
'projectGroupName.indexedObjectName DESC';
} else {
$order[$k] =
'projectGroupName.indexedObjectName IS NULL ASC, '.
'projectGroupName.indexedObjectName ASC';
}
break;
default:
if ($reverse) {
$order[$k] = "task.{$column} ASC";
} else {
$order[$k] = "task.{$column} DESC";
}
break;
}
}
if ($app_order) {
foreach ($app_order as $order_by) {
$order[] = $order_by;
}
if ($reverse) {
$order[] = 'task.id ASC';
} else {
$order[] = 'task.id DESC';
}
}
return 'ORDER BY '.implode(', ', $order);
}
private function buildJoinsClause(AphrontDatabaseConnection $conn_r) {
$edge_table = PhabricatorEdgeConfig::TABLE_NAME_EDGE;
$joins = array();
if ($this->projectPHIDs || $this->includeNoProject) {
$joins[] = qsprintf(
$conn_r,
'%Q JOIN %T project ON project.src = task.phid
AND project.type = %d',
($this->includeNoProject ? 'LEFT' : ''),
$edge_table,
PhabricatorProjectObjectHasProjectEdgeType::EDGECONST);
}
if ($this->shouldJoinBlockingTasks()) {
$joins[] = qsprintf(
$conn_r,
'LEFT JOIN %T blocking ON blocking.src = task.phid '.
'AND blocking.type = %d',
$edge_table,
ManiphestTaskDependedOnByTaskEdgeType::EDGECONST);
}
if ($this->shouldJoinBlockedTasks()) {
$joins[] = qsprintf(
$conn_r,
'LEFT JOIN %T blocked ON blocked.src = task.phid '.
'AND blocked.type = %d',
$edge_table,
ManiphestTaskDependsOnTaskEdgeType::EDGECONST);
}
if ($this->anyProjectPHIDs || $this->anyUserProjectPHIDs) {
$joins[] = qsprintf(
$conn_r,
'JOIN %T anyproject ON anyproject.src = task.phid
AND anyproject.type = %d',
$edge_table,
PhabricatorProjectObjectHasProjectEdgeType::EDGECONST);
}
if ($this->xprojectPHIDs) {
$joins[] = qsprintf(
$conn_r,
'LEFT JOIN %T xproject ON xproject.src = task.phid
AND xproject.type = %d
AND xproject.dst IN (%Ls)',
$edge_table,
PhabricatorProjectObjectHasProjectEdgeType::EDGECONST,
$this->xprojectPHIDs);
}
if ($this->subscriberPHIDs) {
$joins[] = qsprintf(
$conn_r,
'JOIN %T e_ccs ON e_ccs.src = task.phid '.
'AND e_ccs.type = %s '.
'AND e_ccs.dst in (%Ls)',
PhabricatorEdgeConfig::TABLE_NAME_EDGE,
PhabricatorObjectHasSubscriberEdgeType::EDGECONST,
$this->subscriberPHIDs);
}
switch ($this->groupBy) {
case self::GROUP_PROJECT:
$ignore_group_phids = $this->getIgnoreGroupedProjectPHIDs();
if ($ignore_group_phids) {
$joins[] = qsprintf(
$conn_r,
'LEFT JOIN %T projectGroup ON task.phid = projectGroup.src
AND projectGroup.type = %d
AND projectGroup.dst NOT IN (%Ls)',
$edge_table,
PhabricatorProjectObjectHasProjectEdgeType::EDGECONST,
$ignore_group_phids);
} else {
$joins[] = qsprintf(
$conn_r,
'LEFT JOIN %T projectGroup ON task.phid = projectGroup.src
AND projectGroup.type = %d',
$edge_table,
PhabricatorProjectObjectHasProjectEdgeType::EDGECONST);
}
$joins[] = qsprintf(
$conn_r,
'LEFT JOIN %T projectGroupName
ON projectGroup.dst = projectGroupName.indexedObjectPHID',
id(new ManiphestNameIndex())->getTableName());
break;
}
$joins[] = $this->buildApplicationSearchJoinClause($conn_r);
return implode(' ', $joins);
}
private function buildGroupClause(AphrontDatabaseConnection $conn_r) {
$joined_multiple_rows = (count($this->projectPHIDs) > 1) ||
(count($this->anyProjectPHIDs) > 1) ||
$this->shouldJoinBlockingTasks() ||
$this->shouldJoinBlockedTasks() ||
($this->getApplicationSearchMayJoinMultipleRows());
$joined_project_name = ($this->groupBy == self::GROUP_PROJECT);
// If we're joining multiple rows, we need to group the results by the
// task IDs.
if ($joined_multiple_rows) {
if ($joined_project_name) {
return 'GROUP BY task.phid, projectGroup.dst';
} else {
return 'GROUP BY task.phid';
}
} else {
return '';
}
}
/**
* Return project PHIDs which we should ignore when grouping tasks by
* project. For example, if a user issues a query like:
*
* Tasks in all projects: Frontend, Bugs
*
* ...then we don't show "Frontend" or "Bugs" groups in the result set, since
* they're meaningless as all results are in both groups.
*
* Similarly, for queries like:
*
* Tasks in any projects: Public Relations
*
* ...we ignore the single project, as every result is in that project. (In
* the case that there are several "any" projects, we do not ignore them.)
*
* @return list<phid> Project PHIDs which should be ignored in query
* construction.
*/
private function getIgnoreGroupedProjectPHIDs() {
$phids = array();
if ($this->projectPHIDs) {
$phids[] = $this->projectPHIDs;
}
if (count($this->anyProjectPHIDs) == 1) {
$phids[] = $this->anyProjectPHIDs;
}
// Maybe we should also exclude the "excludeProjectPHIDs"? It won't
// impact the results, but we might end up with a better query plan.
// Investigate this on real data? This is likely very rare.
return array_mergev($phids);
}
private function loadCursorObject($id) {
$results = id(new ManiphestTaskQuery())
->setViewer($this->getPagingViewer())
->withIDs(array((int)$id))
->execute();
return head($results);
}
protected function getPagingValue($result) {
$id = $result->getID();
switch ($this->groupBy) {
case self::GROUP_NONE:
return $id;
case self::GROUP_PRIORITY:
return $id.'.'.$result->getPriority();
case self::GROUP_OWNER:
return rtrim($id.'.'.$result->getOwnerPHID(), '.');
case self::GROUP_STATUS:
return $id.'.'.$result->getStatus();
case self::GROUP_PROJECT:
return rtrim($id.'.'.$result->getGroupByProjectPHID(), '.');
default:
throw new Exception("Unknown group query '{$this->groupBy}'!");
}
}
protected function buildPagingClause(AphrontDatabaseConnection $conn_r) {
$default = parent::buildPagingClause($conn_r);
$before_id = $this->getBeforeID();
$after_id = $this->getAfterID();
if (!$before_id && !$after_id) {
return $default;
}
$cursor_id = nonempty($before_id, $after_id);
$cursor_parts = explode('.', $cursor_id, 2);
$task_id = $cursor_parts[0];
$group_id = idx($cursor_parts, 1);
$cursor = $this->loadCursorObject($task_id);
if (!$cursor) {
return null;
}
$columns = array();
switch ($this->groupBy) {
case self::GROUP_NONE:
break;
case self::GROUP_PRIORITY:
$columns[] = array(
'name' => 'task.priority',
'value' => (int)$group_id,
'type' => 'int',
);
break;
case self::GROUP_OWNER:
$columns[] = array(
'name' => '(task.ownerOrdering IS NULL)',
'value' => (int)(strlen($group_id) ? 0 : 1),
'type' => 'int',
);
if ($group_id) {
$paging_users = id(new PhabricatorPeopleQuery())
->setViewer($this->getViewer())
->withPHIDs(array($group_id))
->execute();
if (!$paging_users) {
return null;
}
$columns[] = array(
'name' => 'task.ownerOrdering',
'value' => head($paging_users)->getUsername(),
'type' => 'string',
'reverse' => true,
);
}
break;
case self::GROUP_STATUS:
$columns[] = array(
'name' => 'task.status',
'value' => $group_id,
'type' => 'string',
);
break;
case self::GROUP_PROJECT:
$columns[] = array(
'name' => '(projectGroupName.indexedObjectName IS NULL)',
'value' => (int)(strlen($group_id) ? 0 : 1),
'type' => 'int',
);
if ($group_id) {
$paging_projects = id(new PhabricatorProjectQuery())
->setViewer($this->getViewer())
->withPHIDs(array($group_id))
->execute();
if (!$paging_projects) {
return null;
}
$columns[] = array(
'name' => 'projectGroupName.indexedObjectName',
'value' => head($paging_projects)->getName(),
'type' => 'string',
'reverse' => true,
);
}
break;
default:
throw new Exception("Unknown group query '{$this->groupBy}'!");
}
$app_columns = $this->buildApplicationSearchPagination($conn_r, $cursor);
if ($app_columns) {
$columns = array_merge($columns, $app_columns);
$columns[] = array(
'name' => 'task.id',
'value' => (int)$cursor->getID(),
'type' => 'int',
);
} else {
switch ($this->orderBy) {
case self::ORDER_PRIORITY:
if ($this->groupBy != self::GROUP_PRIORITY) {
$columns[] = array(
'name' => 'task.priority',
'value' => (int)$cursor->getPriority(),
'type' => 'int',
);
}
$columns[] = array(
'name' => 'task.subpriority',
'value' => (int)$cursor->getSubpriority(),
'type' => 'int',
'reverse' => true,
);
$columns[] = array(
'name' => 'task.dateModified',
'value' => (int)$cursor->getDateModified(),
'type' => 'int',
);
break;
case self::ORDER_CREATED:
$columns[] = array(
'name' => 'task.id',
'value' => (int)$cursor->getID(),
'type' => 'int',
);
break;
case self::ORDER_MODIFIED:
$columns[] = array(
'name' => 'task.dateModified',
'value' => (int)$cursor->getDateModified(),
'type' => 'int',
);
break;
case self::ORDER_TITLE:
$columns[] = array(
'name' => 'task.title',
'value' => $cursor->getTitle(),
'type' => 'string',
);
$columns[] = array(
'name' => 'task.id',
'value' => $cursor->getID(),
'type' => 'int',
);
break;
default:
throw new Exception("Unknown order query '{$this->orderBy}'!");
}
}
return $this->buildPagingClauseFromMultipleColumns(
$conn_r,
$columns,
array(
'reversed' => (bool)($before_id xor $this->getReversePaging()),
));
}
protected function getApplicationSearchObjectPHIDColumn() {
return 'task.phid';
}
public function getQueryApplicationClass() {
return 'PhabricatorManiphestApplication';
}
}
diff --git a/src/applications/meta/query/PhabricatorApplicationQuery.php b/src/applications/meta/query/PhabricatorApplicationQuery.php
index 45a6f2f158..cd42089fc6 100644
--- a/src/applications/meta/query/PhabricatorApplicationQuery.php
+++ b/src/applications/meta/query/PhabricatorApplicationQuery.php
@@ -1,159 +1,159 @@
<?php
final class PhabricatorApplicationQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
private $installed;
private $prototypes;
private $firstParty;
private $nameContains;
private $unlisted;
private $classes;
private $launchable;
private $phids;
const ORDER_APPLICATION = 'order:application';
const ORDER_NAME = 'order:name';
private $order = self::ORDER_APPLICATION;
public function withNameContains($name_contains) {
$this->nameContains = $name_contains;
return $this;
}
public function withInstalled($installed) {
$this->installed = $installed;
return $this;
}
public function withPrototypes($prototypes) {
$this->prototypes = $prototypes;
return $this;
}
public function withFirstParty($first_party) {
$this->firstParty = $first_party;
return $this;
}
public function withUnlisted($unlisted) {
$this->unlisted = $unlisted;
return $this;
}
public function withLaunchable($launchable) {
$this->launchable = $launchable;
return $this;
}
public function withClasses(array $classes) {
$this->classes = $classes;
return $this;
}
public function withPHIDs(array $phids) {
$this->phids = $phids;
return $this;
}
public function setOrder($order) {
$this->order = $order;
return $this;
}
- public function loadPage() {
+ protected function loadPage() {
$apps = PhabricatorApplication::getAllApplications();
if ($this->classes) {
$classes = array_fuse($this->classes);
foreach ($apps as $key => $app) {
if (empty($classes[get_class($app)])) {
unset($apps[$key]);
}
}
}
if ($this->phids) {
$phids = array_fuse($this->phids);
foreach ($apps as $key => $app) {
if (empty($phids[$app->getPHID()])) {
unset($apps[$key]);
}
}
}
if (strlen($this->nameContains)) {
foreach ($apps as $key => $app) {
if (stripos($app->getName(), $this->nameContains) === false) {
unset($apps[$key]);
}
}
}
if ($this->installed !== null) {
foreach ($apps as $key => $app) {
if ($app->isInstalled() != $this->installed) {
unset($apps[$key]);
}
}
}
if ($this->prototypes !== null) {
foreach ($apps as $key => $app) {
if ($app->isPrototype() != $this->prototypes) {
unset($apps[$key]);
}
}
}
if ($this->firstParty !== null) {
foreach ($apps as $key => $app) {
if ($app->isFirstParty() != $this->firstParty) {
unset($apps[$key]);
}
}
}
if ($this->unlisted !== null) {
foreach ($apps as $key => $app) {
if ($app->isUnlisted() != $this->unlisted) {
unset($apps[$key]);
}
}
}
if ($this->launchable !== null) {
foreach ($apps as $key => $app) {
if ($app->isLaunchable() != $this->launchable) {
unset($apps[$key]);
}
}
}
switch ($this->order) {
case self::ORDER_NAME:
$apps = msort($apps, 'getName');
break;
case self::ORDER_APPLICATION:
$apps = $apps;
break;
default:
throw new Exception(
pht('Unknown order "%s"!', $this->order));
}
return $apps;
}
public function getQueryApplicationClass() {
// NOTE: Although this belongs to the "Applications" application, trying
// to filter its results just leaves us recursing indefinitely. Users
// always have access to applications regardless of other policy settings
// anyway.
return null;
}
}
diff --git a/src/applications/nuance/query/NuanceItemQuery.php b/src/applications/nuance/query/NuanceItemQuery.php
index d37c2176f8..5264c4b527 100644
--- a/src/applications/nuance/query/NuanceItemQuery.php
+++ b/src/applications/nuance/query/NuanceItemQuery.php
@@ -1,70 +1,70 @@
<?php
final class NuanceItemQuery
extends NuanceQuery {
private $ids;
private $phids;
private $sourceIDs;
public function withIDs(array $ids) {
$this->ids = $ids;
return $this;
}
public function withPHIDs(array $phids) {
$this->phids = $phids;
return $this;
}
public function withSourceIDs($source_ids) {
$this->sourceIDs = $source_ids;
return $this;
}
- public function loadPage() {
+ protected function loadPage() {
$table = new NuanceItem();
$conn_r = $table->establishConnection('r');
$data = queryfx_all(
$conn_r,
'SELECT FROM %T %Q %Q %Q',
$table->getTableName(),
$this->buildWhereClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
return $table->loadAllFromArray($data);
}
protected function buildWhereClause($conn_r) {
$where = array();
$where[] = $this->buildPagingClause($conn_r);
if ($this->sourceID) {
$where[] = qsprintf(
$conn_r,
'sourceID IN (%Ld)',
$this->sourceIDs);
}
if ($this->ids) {
$where[] = qsprintf(
$conn_r,
'id IN (%Ld)',
$this->ids);
}
if ($this->phids) {
$where[] = qsprintf(
$conn_r,
'phid IN (%Ls)',
$this->phids);
}
return $this->formatWhereClause($where);
}
}
diff --git a/src/applications/nuance/query/NuanceQueueQuery.php b/src/applications/nuance/query/NuanceQueueQuery.php
index 942753dbf4..b4a067f01c 100644
--- a/src/applications/nuance/query/NuanceQueueQuery.php
+++ b/src/applications/nuance/query/NuanceQueueQuery.php
@@ -1,56 +1,56 @@
<?php
final class NuanceQueueQuery
extends NuanceQuery {
private $ids;
private $phids;
public function withIDs(array $ids) {
$this->ids = $ids;
return $this;
}
public function withPHIDs(array $phids) {
$this->phids = $phids;
return $this;
}
- public function loadPage() {
+ protected function loadPage() {
$table = new NuanceQueue();
$conn_r = $table->establishConnection('r');
$data = queryfx_all(
$conn_r,
'SELECT FROM %T %Q %Q %Q',
$table->getTableName(),
$this->buildWhereClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
return $table->loadAllFromArray($data);
}
protected function buildWhereClause($conn_r) {
$where = array();
$where[] = $this->buildPagingClause($conn_r);
if ($this->ids) {
$where[] = qsprintf(
$conn_r,
'id IN (%Ld)',
$this->ids);
}
if ($this->phids) {
$where[] = qsprintf(
$conn_r,
'phid IN (%Ls)',
$this->phids);
}
return $this->formatWhereClause($where);
}
}
diff --git a/src/applications/nuance/query/NuanceRequestorQuery.php b/src/applications/nuance/query/NuanceRequestorQuery.php
index a1df9b98f3..e23cc71343 100644
--- a/src/applications/nuance/query/NuanceRequestorQuery.php
+++ b/src/applications/nuance/query/NuanceRequestorQuery.php
@@ -1,56 +1,56 @@
<?php
final class NuanceRequestorQuery
extends NuanceQuery {
private $ids;
private $phids;
public function withIDs(array $ids) {
$this->ids = $ids;
return $this;
}
public function withPHIDs(array $phids) {
$this->phids = $phids;
return $this;
}
- public function loadPage() {
+ protected function loadPage() {
$table = new NuanceRequestor();
$conn_r = $table->establishConnection('r');
$data = queryfx_all(
$conn_r,
'SELECT FROM %T %Q %Q %Q',
$table->getTableName(),
$this->buildWhereClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
return $table->loadAllFromArray($data);
}
protected function buildWhereClause($conn_r) {
$where = array();
$where[] = $this->buildPagingClause($conn_r);
if ($this->ids) {
$where[] = qsprintf(
$conn_r,
'id IN (%Ld)',
$this->ids);
}
if ($this->phids) {
$where[] = qsprintf(
$conn_r,
'phid IN (%Ls)',
$this->phids);
}
return $this->formatWhereClause($where);
}
}
diff --git a/src/applications/nuance/query/NuanceSourceQuery.php b/src/applications/nuance/query/NuanceSourceQuery.php
index d56dbe0eda..3a177a4e42 100644
--- a/src/applications/nuance/query/NuanceSourceQuery.php
+++ b/src/applications/nuance/query/NuanceSourceQuery.php
@@ -1,83 +1,83 @@
<?php
final class NuanceSourceQuery
extends NuanceQuery {
private $ids;
private $phids;
private $creatorPHIDs;
private $types;
public function withIDs(array $ids) {
$this->ids = $ids;
return $this;
}
public function withPHIDs(array $phids) {
$this->phids = $phids;
return $this;
}
public function withCreatorPHIDs(array $phids) {
$this->CreatorPHIDs = $phids;
return $this;
}
public function withTypes($types) {
$this->types = $types;
return $this;
}
- public function loadPage() {
+ protected function loadPage() {
$table = new NuanceSource();
$conn_r = $table->establishConnection('r');
$data = queryfx_all(
$conn_r,
'SELECT * FROM %T %Q %Q %Q',
$table->getTableName(),
$this->buildWhereClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
return $table->loadAllFromArray($data);
}
protected function buildWhereClause($conn_r) {
$where = array();
$where[] = $this->buildPagingClause($conn_r);
if ($this->creatorPHIDs) {
$where[] = qsprintf(
$conn_r,
'creatorPHID IN (%Ls)',
$this->creatorPHIDs);
}
if ($this->types) {
$where[] = qsprintf(
$conn_r,
'type IN (%Ld)',
$this->types);
}
if ($this->ids) {
$where[] = qsprintf(
$conn_r,
'id IN (%Ld)',
$this->ids);
}
if ($this->phids) {
$where[] = qsprintf(
$conn_r,
'phid IN (%Ls)',
$this->phids);
}
return $this->formatWhereClause($where);
}
}
diff --git a/src/applications/oauthserver/query/PhabricatorOAuthClientAuthorizationQuery.php b/src/applications/oauthserver/query/PhabricatorOAuthClientAuthorizationQuery.php
index 9f2c0b38b3..754e3474ab 100644
--- a/src/applications/oauthserver/query/PhabricatorOAuthClientAuthorizationQuery.php
+++ b/src/applications/oauthserver/query/PhabricatorOAuthClientAuthorizationQuery.php
@@ -1,95 +1,95 @@
<?php
final class PhabricatorOAuthClientAuthorizationQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
private $phids;
private $userPHIDs;
private $clientPHIDs;
public function witHPHIDs(array $phids) {
$this->phids = $phids;
return $this;
}
public function withUserPHIDs(array $phids) {
$this->userPHIDs = $phids;
return $this;
}
public function withClientPHIDs(array $phids) {
$this->clientPHIDs = $phids;
return $this;
}
- public function loadPage() {
+ protected function loadPage() {
$table = new PhabricatorOAuthClientAuthorization();
$conn_r = $table->establishConnection('r');
$data = queryfx_all(
$conn_r,
'SELECT * FROM %T auth %Q %Q %Q',
$table->getTableName(),
$this->buildWhereClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
return $table->loadAllFromArray($data);
}
- public function willFilterPage(array $authorizations) {
+ protected function willFilterPage(array $authorizations) {
$client_phids = mpull($authorizations, 'getClientPHID');
$clients = id(new PhabricatorOAuthServerClientQuery())
->setViewer($this->getViewer())
->setParentQuery($this)
->withPHIDs($client_phids)
->execute();
$clients = mpull($clients, null, 'getPHID');
foreach ($authorizations as $key => $authorization) {
$client = idx($clients, $authorization->getClientPHID());
if (!$client) {
unset($authorizations[$key]);
continue;
}
$authorization->attachClient($client);
}
return $authorizations;
}
private function buildWhereClause($conn_r) {
$where = array();
if ($this->phids) {
$where[] = qsprintf(
$conn_r,
'phid IN (%Ls)',
$this->phids);
}
if ($this->userPHIDs) {
$where[] = qsprintf(
$conn_r,
'userPHID IN (%Ls)',
$this->userPHIDs);
}
if ($this->clientPHIDs) {
$where[] = qsprintf(
$conn_r,
'clientPHID IN (%Ls)',
$this->clientPHIDs);
}
$where[] = $this->buildPagingClause($conn_r);
return $this->formatWhereClause($where);
}
public function getQueryApplicationClass() {
return 'PhabricatorOAuthServerApplication';
}
}
diff --git a/src/applications/oauthserver/query/PhabricatorOAuthServerClientQuery.php b/src/applications/oauthserver/query/PhabricatorOAuthServerClientQuery.php
index 9f181aefe4..bf22a2a701 100644
--- a/src/applications/oauthserver/query/PhabricatorOAuthServerClientQuery.php
+++ b/src/applications/oauthserver/query/PhabricatorOAuthServerClientQuery.php
@@ -1,73 +1,73 @@
<?php
final class PhabricatorOAuthServerClientQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
private $ids;
private $phids;
private $creatorPHIDs;
public function withIDs(array $ids) {
$this->ids = $ids;
return $this;
}
public function withPHIDs(array $phids) {
$this->phids = $phids;
return $this;
}
public function withCreatorPHIDs(array $phids) {
$this->creatorPHIDs = $phids;
return $this;
}
- public function loadPage() {
+ protected function loadPage() {
$table = new PhabricatorOAuthServerClient();
$conn_r = $table->establishConnection('r');
$data = queryfx_all(
$conn_r,
'SELECT * FROM %T client %Q %Q %Q',
$table->getTableName(),
$this->buildWhereClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
return $table->loadAllFromArray($data);
}
private function buildWhereClause($conn_r) {
$where = array();
if ($this->ids) {
$where[] = qsprintf(
$conn_r,
'id IN (%Ld)',
$this->ids);
}
if ($this->phids) {
$where[] = qsprintf(
$conn_r,
'phid IN (%Ls)',
$this->phids);
}
if ($this->creatorPHIDs) {
$where[] = qsprintf(
$conn_r,
'creatorPHID IN (%Ls)',
$this->creatorPHIDs);
}
$where[] = $this->buildPagingClause($conn_r);
return $this->formatWhereClause($where);
}
public function getQueryApplicationClass() {
return 'PhabricatorOAuthServerApplication';
}
}
diff --git a/src/applications/people/query/PhabricatorPeopleLogQuery.php b/src/applications/people/query/PhabricatorPeopleLogQuery.php
index a12a07310b..3315234d12 100644
--- a/src/applications/people/query/PhabricatorPeopleLogQuery.php
+++ b/src/applications/people/query/PhabricatorPeopleLogQuery.php
@@ -1,113 +1,113 @@
<?php
final class PhabricatorPeopleLogQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
private $actorPHIDs;
private $userPHIDs;
private $relatedPHIDs;
private $sessionKeys;
private $actions;
private $remoteAddressPrefix;
public function withActorPHIDs(array $actor_phids) {
$this->actorPHIDs = $actor_phids;
return $this;
}
public function withUserPHIDs(array $user_phids) {
$this->userPHIDs = $user_phids;
return $this;
}
public function withRelatedPHIDs(array $related_phids) {
$this->relatedPHIDs = $related_phids;
return $this;
}
public function withSessionKeys(array $session_keys) {
$this->sessionKeys = $session_keys;
return $this;
}
public function withActions(array $actions) {
$this->actions = $actions;
return $this;
}
public function withRemoteAddressPrefix($remote_address_prefix) {
$this->remoteAddressPrefix = $remote_address_prefix;
return $this;
}
- public function loadPage() {
+ protected function loadPage() {
$table = new PhabricatorUserLog();
$conn_r = $table->establishConnection('r');
$data = queryfx_all(
$conn_r,
'SELECT * FROM %T %Q %Q %Q',
$table->getTableName(),
$this->buildWhereClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
return $table->loadAllFromArray($data);
}
private function buildWhereClause($conn_r) {
$where = array();
if ($this->actorPHIDs !== null) {
$where[] = qsprintf(
$conn_r,
'actorPHID IN (%Ls)',
$this->actorPHIDs);
}
if ($this->userPHIDs !== null) {
$where[] = qsprintf(
$conn_r,
'userPHID IN (%Ls)',
$this->userPHIDs);
}
if ($this->relatedPHIDs !== null) {
$where[] = qsprintf(
$conn_r,
'actorPHID IN (%Ls) OR userPHID IN (%Ls)',
$this->relatedPHIDs,
$this->relatedPHIDs);
}
if ($this->sessionKeys !== null) {
$where[] = qsprintf(
$conn_r,
'session IN (%Ls)',
$this->sessionKeys);
}
if ($this->actions !== null) {
$where[] = qsprintf(
$conn_r,
'action IN (%Ls)',
$this->actions);
}
if ($this->remoteAddressPrefix !== null) {
$where[] = qsprintf(
$conn_r,
'remoteAddr LIKE %>',
$this->remoteAddressPrefix);
}
$where[] = $this->buildPagingClause($conn_r);
return $this->formatWhereClause($where);
}
public function getQueryApplicationClass() {
return 'PhabricatorPeopleApplication';
}
}
diff --git a/src/applications/people/query/PhabricatorPeopleQuery.php b/src/applications/people/query/PhabricatorPeopleQuery.php
index f61f40ae0c..f76ab9e5aa 100644
--- a/src/applications/people/query/PhabricatorPeopleQuery.php
+++ b/src/applications/people/query/PhabricatorPeopleQuery.php
@@ -1,303 +1,303 @@
<?php
final class PhabricatorPeopleQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
private $usernames;
private $realnames;
private $emails;
private $phids;
private $ids;
private $dateCreatedAfter;
private $dateCreatedBefore;
private $isAdmin;
private $isSystemAgent;
private $isDisabled;
private $isApproved;
private $nameLike;
private $needPrimaryEmail;
private $needProfile;
private $needProfileImage;
private $needStatus;
public function withIDs(array $ids) {
$this->ids = $ids;
return $this;
}
public function withPHIDs(array $phids) {
$this->phids = $phids;
return $this;
}
public function withEmails(array $emails) {
$this->emails = $emails;
return $this;
}
public function withRealnames(array $realnames) {
$this->realnames = $realnames;
return $this;
}
public function withUsernames(array $usernames) {
$this->usernames = $usernames;
return $this;
}
public function withDateCreatedBefore($date_created_before) {
$this->dateCreatedBefore = $date_created_before;
return $this;
}
public function withDateCreatedAfter($date_created_after) {
$this->dateCreatedAfter = $date_created_after;
return $this;
}
public function withIsAdmin($admin) {
$this->isAdmin = $admin;
return $this;
}
public function withIsSystemAgent($system_agent) {
$this->isSystemAgent = $system_agent;
return $this;
}
public function withIsDisabled($disabled) {
$this->isDisabled = $disabled;
return $this;
}
public function withIsApproved($approved) {
$this->isApproved = $approved;
return $this;
}
public function withNameLike($like) {
$this->nameLike = $like;
return $this;
}
public function needPrimaryEmail($need) {
$this->needPrimaryEmail = $need;
return $this;
}
public function needProfile($need) {
$this->needProfile = $need;
return $this;
}
public function needProfileImage($need) {
$this->needProfileImage = $need;
return $this;
}
public function needStatus($need) {
$this->needStatus = $need;
return $this;
}
- public function loadPage() {
+ protected function loadPage() {
$table = new PhabricatorUser();
$conn_r = $table->establishConnection('r');
$data = queryfx_all(
$conn_r,
'SELECT * FROM %T user %Q %Q %Q %Q %Q',
$table->getTableName(),
$this->buildJoinsClause($conn_r),
$this->buildWhereClause($conn_r),
$this->buildApplicationSearchGroupClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
if ($this->needPrimaryEmail) {
$table->putInSet(new LiskDAOSet());
}
return $table->loadAllFromArray($data);
}
protected function didFilterPage(array $users) {
if ($this->needProfile) {
$user_list = mpull($users, null, 'getPHID');
$profiles = new PhabricatorUserProfile();
$profiles = $profiles->loadAllWhere('userPHID IN (%Ls)',
array_keys($user_list));
$profiles = mpull($profiles, null, 'getUserPHID');
foreach ($user_list as $user_phid => $user) {
$profile = idx($profiles, $user_phid);
if (!$profile) {
$profile = new PhabricatorUserProfile();
$profile->setUserPHID($user_phid);
}
$user->attachUserProfile($profile);
}
}
if ($this->needProfileImage) {
$user_profile_file_phids = mpull($users, 'getProfileImagePHID');
$user_profile_file_phids = array_filter($user_profile_file_phids);
if ($user_profile_file_phids) {
$files = id(new PhabricatorFileQuery())
->setParentQuery($this)
->setViewer($this->getViewer())
->withPHIDs($user_profile_file_phids)
->execute();
$files = mpull($files, null, 'getPHID');
} else {
$files = array();
}
foreach ($users as $user) {
$image_phid = $user->getProfileImagePHID();
if (isset($files[$image_phid])) {
$profile_image_uri = $files[$image_phid]->getBestURI();
} else {
$profile_image_uri = PhabricatorUser::getDefaultProfileImageURI();
}
$user->attachProfileImageURI($profile_image_uri);
}
}
if ($this->needStatus) {
$user_list = mpull($users, null, 'getPHID');
$statuses = id(new PhabricatorCalendarEvent())->loadCurrentStatuses(
array_keys($user_list));
foreach ($user_list as $phid => $user) {
$status = idx($statuses, $phid);
if ($status) {
$user->attachStatus($status);
}
}
}
return $users;
}
private function buildJoinsClause($conn_r) {
$joins = array();
if ($this->emails) {
$email_table = new PhabricatorUserEmail();
$joins[] = qsprintf(
$conn_r,
'JOIN %T email ON email.userPHID = user.PHID',
$email_table->getTableName());
}
$joins[] = $this->buildApplicationSearchJoinClause($conn_r);
$joins = implode(' ', $joins);
return $joins;
}
private function buildWhereClause($conn_r) {
$where = array();
if ($this->usernames !== null) {
$where[] = qsprintf(
$conn_r,
'user.userName IN (%Ls)',
$this->usernames);
}
if ($this->emails !== null) {
$where[] = qsprintf(
$conn_r,
'email.address IN (%Ls)',
$this->emails);
}
if ($this->realnames !== null) {
$where[] = qsprintf(
$conn_r,
'user.realName IN (%Ls)',
$this->realnames);
}
if ($this->phids !== null) {
$where[] = qsprintf(
$conn_r,
'user.phid IN (%Ls)',
$this->phids);
}
if ($this->ids !== null) {
$where[] = qsprintf(
$conn_r,
'user.id IN (%Ld)',
$this->ids);
}
if ($this->dateCreatedAfter) {
$where[] = qsprintf(
$conn_r,
'user.dateCreated >= %d',
$this->dateCreatedAfter);
}
if ($this->dateCreatedBefore) {
$where[] = qsprintf(
$conn_r,
'user.dateCreated <= %d',
$this->dateCreatedBefore);
}
if ($this->isAdmin) {
$where[] = qsprintf(
$conn_r,
'user.isAdmin = 1');
}
if ($this->isDisabled !== null) {
$where[] = qsprintf(
$conn_r,
'user.isDisabled = %d',
(int)$this->isDisabled);
}
if ($this->isApproved !== null) {
$where[] = qsprintf(
$conn_r,
'user.isApproved = %d',
(int)$this->isApproved);
}
if ($this->isSystemAgent) {
$where[] = qsprintf(
$conn_r,
'user.isSystemAgent = 1');
}
if (strlen($this->nameLike)) {
$where[] = qsprintf(
$conn_r,
'user.username LIKE %~ OR user.realname LIKE %~',
$this->nameLike,
$this->nameLike);
}
$where[] = $this->buildPagingClause($conn_r);
return $this->formatWhereClause($where);
}
protected function getPagingColumn() {
return 'user.id';
}
protected function getApplicationSearchObjectPHIDColumn() {
return 'user.phid';
}
public function getQueryApplicationClass() {
return 'PhabricatorPeopleApplication';
}
}
diff --git a/src/applications/phid/query/PhabricatorHandleQuery.php b/src/applications/phid/query/PhabricatorHandleQuery.php
index c3e923c0a7..296116312b 100644
--- a/src/applications/phid/query/PhabricatorHandleQuery.php
+++ b/src/applications/phid/query/PhabricatorHandleQuery.php
@@ -1,74 +1,74 @@
<?php
final class PhabricatorHandleQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
private $phids = array();
public function withPHIDs(array $phids) {
$this->phids = $phids;
return $this;
}
- public function loadPage() {
+ protected function loadPage() {
$types = PhabricatorPHIDType::getAllTypes();
$phids = array_unique($this->phids);
if (!$phids) {
return array();
}
$object_query = id(new PhabricatorObjectQuery())
->withPHIDs($phids)
->setViewer($this->getViewer());
$objects = $object_query->execute();
$filtered = $object_query->getPolicyFilteredPHIDs();
$groups = array();
foreach ($phids as $phid) {
$type = phid_get_type($phid);
$groups[$type][] = $phid;
}
$results = array();
foreach ($groups as $type => $phid_group) {
$handles = array();
foreach ($phid_group as $key => $phid) {
if (isset($handles[$phid])) {
unset($phid_group[$key]);
// The input had a duplicate PHID; just skip it.
continue;
}
$handles[$phid] = id(new PhabricatorObjectHandle())
->setType($type)
->setPHID($phid);
if (isset($objects[$phid])) {
$handles[$phid]->setComplete(true);
} else if (isset($filtered[$phid])) {
$handles[$phid]->setPolicyFiltered(true);
}
}
if (isset($types[$type])) {
$type_objects = array_select_keys($objects, $phid_group);
if ($type_objects) {
$have_object_phids = array_keys($type_objects);
$types[$type]->loadHandles(
$this,
array_select_keys($handles, $have_object_phids),
$type_objects);
}
}
$results += $handles;
}
return $results;
}
public function getQueryApplicationClass() {
return null;
}
}
diff --git a/src/applications/phid/query/PhabricatorObjectQuery.php b/src/applications/phid/query/PhabricatorObjectQuery.php
index ba42a91644..49d238c6a9 100644
--- a/src/applications/phid/query/PhabricatorObjectQuery.php
+++ b/src/applications/phid/query/PhabricatorObjectQuery.php
@@ -1,165 +1,165 @@
<?php
final class PhabricatorObjectQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
private $phids = array();
private $names = array();
private $types;
private $namedResults;
public function withPHIDs(array $phids) {
$this->phids = $phids;
return $this;
}
public function withNames(array $names) {
$this->names = $names;
return $this;
}
public function withTypes(array $types) {
$this->types = $types;
return $this;
}
- public function loadPage() {
+ protected function loadPage() {
if ($this->namedResults === null) {
$this->namedResults = array();
}
$types = PhabricatorPHIDType::getAllTypes();
if ($this->types) {
$types = array_select_keys($types, $this->types);
}
$names = array_unique($this->names);
$phids = $this->phids;
// We allow objects to be named by their PHID in addition to their normal
// name so that, e.g., CLI tools which accept object names can also accept
// PHIDs and work as users expect.
$actually_phids = array();
if ($names) {
foreach ($names as $key => $name) {
if (!strncmp($name, 'PHID-', 5)) {
$actually_phids[] = $name;
$phids[] = $name;
unset($names[$key]);
}
}
}
$phids = array_unique($phids);
if ($names) {
$name_results = $this->loadObjectsByName($types, $names);
} else {
$name_results = array();
}
if ($phids) {
$phid_results = $this->loadObjectsByPHID($types, $phids);
} else {
$phid_results = array();
}
foreach ($actually_phids as $phid) {
if (isset($phid_results[$phid])) {
$name_results[$phid] = $phid_results[$phid];
}
}
$this->namedResults += $name_results;
return $phid_results + mpull($name_results, null, 'getPHID');
}
public function getNamedResults() {
if ($this->namedResults === null) {
throw new Exception('Call execute() before getNamedResults()!');
}
return $this->namedResults;
}
private function loadObjectsByName(array $types, array $names) {
$groups = array();
foreach ($names as $name) {
foreach ($types as $type => $type_impl) {
if (!$type_impl->canLoadNamedObject($name)) {
continue;
}
$groups[$type][] = $name;
break;
}
}
$results = array();
foreach ($groups as $type => $group) {
$results += $types[$type]->loadNamedObjects($this, $group);
}
return $results;
}
private function loadObjectsByPHID(array $types, array $phids) {
$results = array();
$workspace = $this->getObjectsFromWorkspace($phids);
foreach ($phids as $key => $phid) {
if (isset($workspace[$phid])) {
$results[$phid] = $workspace[$phid];
unset($phids[$key]);
}
}
if (!$phids) {
return $results;
}
$groups = array();
foreach ($phids as $phid) {
$type = phid_get_type($phid);
$groups[$type][] = $phid;
}
foreach ($groups as $type => $group) {
if (isset($types[$type])) {
$objects = $types[$type]->loadObjects($this, $group);
$results += mpull($objects, null, 'getPHID');
}
}
return $results;
}
protected function didFilterResults(array $filtered) {
foreach ($this->namedResults as $name => $result) {
if (isset($filtered[$result->getPHID()])) {
unset($this->namedResults[$name]);
}
}
}
/**
* This query disables policy filtering if the only required capability is
* the view capability.
*
* The view capability is always checked in the subqueries, so we do not need
* to re-filter results. For any other set of required capabilities, we do.
*/
protected function shouldDisablePolicyFiltering() {
$view_capability = PhabricatorPolicyCapability::CAN_VIEW;
if ($this->getRequiredCapabilities() === array($view_capability)) {
return true;
}
return false;
}
public function getQueryApplicationClass() {
return null;
}
}
diff --git a/src/applications/phragment/query/PhragmentFragmentQuery.php b/src/applications/phragment/query/PhragmentFragmentQuery.php
index a36ebf6a41..173acfb1ce 100644
--- a/src/applications/phragment/query/PhragmentFragmentQuery.php
+++ b/src/applications/phragment/query/PhragmentFragmentQuery.php
@@ -1,130 +1,130 @@
<?php
final class PhragmentFragmentQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
private $ids;
private $phids;
private $paths;
private $leadingPath;
private $depths;
private $needLatestVersion;
public function withIDs(array $ids) {
$this->ids = $ids;
return $this;
}
public function withPHIDs(array $phids) {
$this->phids = $phids;
return $this;
}
public function withPaths(array $paths) {
$this->paths = $paths;
return $this;
}
public function withLeadingPath($path) {
$this->leadingPath = $path;
return $this;
}
public function withDepths($depths) {
$this->depths = $depths;
return $this;
}
public function needLatestVersion($need_latest_version) {
$this->needLatestVersion = $need_latest_version;
return $this;
}
- public function loadPage() {
+ protected function loadPage() {
$table = new PhragmentFragment();
$conn_r = $table->establishConnection('r');
$data = queryfx_all(
$conn_r,
'SELECT * FROM %T %Q %Q %Q',
$table->getTableName(),
$this->buildWhereClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
return $table->loadAllFromArray($data);
}
protected function buildWhereClause($conn_r) {
$where = array();
if ($this->ids) {
$where[] = qsprintf(
$conn_r,
'id IN (%Ld)',
$this->ids);
}
if ($this->phids) {
$where[] = qsprintf(
$conn_r,
'phid IN (%Ls)',
$this->phids);
}
if ($this->paths) {
$where[] = qsprintf(
$conn_r,
'path IN (%Ls)',
$this->paths);
}
if ($this->leadingPath) {
$where[] = qsprintf(
$conn_r,
'path LIKE %>',
$this->leadingPath);
}
if ($this->depths) {
$where[] = qsprintf(
$conn_r,
'depth IN (%Ld)',
$this->depths);
}
$where[] = $this->buildPagingClause($conn_r);
return $this->formatWhereClause($where);
}
protected function didFilterPage(array $page) {
if ($this->needLatestVersion) {
$versions = array();
$version_phids = array_filter(mpull($page, 'getLatestVersionPHID'));
if ($version_phids) {
$versions = id(new PhabricatorObjectQuery())
->setViewer($this->getViewer())
->withPHIDs($version_phids)
->setParentQuery($this)
->execute();
$versions = mpull($versions, null, 'getPHID');
}
foreach ($page as $key => $fragment) {
$version_phid = $fragment->getLatestVersionPHID();
if (empty($versions[$version_phid])) {
continue;
}
$fragment->attachLatestVersion($versions[$version_phid]);
}
}
return $page;
}
public function getQueryApplicationClass() {
return 'PhabricatorPhragmentApplication';
}
}
diff --git a/src/applications/phragment/query/PhragmentFragmentVersionQuery.php b/src/applications/phragment/query/PhragmentFragmentVersionQuery.php
index 2bc76ae53c..4acbd0f636 100644
--- a/src/applications/phragment/query/PhragmentFragmentVersionQuery.php
+++ b/src/applications/phragment/query/PhragmentFragmentVersionQuery.php
@@ -1,123 +1,123 @@
<?php
final class PhragmentFragmentVersionQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
private $ids;
private $phids;
private $fragmentPHIDs;
private $sequences;
private $sequenceBefore;
public function withIDs(array $ids) {
$this->ids = $ids;
return $this;
}
public function withPHIDs(array $phids) {
$this->phids = $phids;
return $this;
}
public function withFragmentPHIDs(array $fragment_phids) {
$this->fragmentPHIDs = $fragment_phids;
return $this;
}
public function withSequences(array $sequences) {
$this->sequences = $sequences;
return $this;
}
public function withSequenceBefore($current) {
$this->sequenceBefore = $current;
return $this;
}
- public function loadPage() {
+ protected function loadPage() {
$table = new PhragmentFragmentVersion();
$conn_r = $table->establishConnection('r');
$data = queryfx_all(
$conn_r,
'SELECT * FROM %T %Q %Q %Q',
$table->getTableName(),
$this->buildWhereClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
return $table->loadAllFromArray($data);
}
protected function buildWhereClause($conn_r) {
$where = array();
if ($this->ids) {
$where[] = qsprintf(
$conn_r,
'id IN (%Ld)',
$this->ids);
}
if ($this->phids) {
$where[] = qsprintf(
$conn_r,
'phid IN (%Ls)',
$this->phids);
}
if ($this->fragmentPHIDs) {
$where[] = qsprintf(
$conn_r,
'fragmentPHID IN (%Ls)',
$this->fragmentPHIDs);
}
if ($this->sequences) {
$where[] = qsprintf(
$conn_r,
'sequence IN (%Ld)',
$this->sequences);
}
if ($this->sequenceBefore !== null) {
$where[] = qsprintf(
$conn_r,
'sequence < %d',
$this->sequenceBefore);
}
$where[] = $this->buildPagingClause($conn_r);
return $this->formatWhereClause($where);
}
protected function willFilterPage(array $page) {
$fragments = array();
$fragment_phids = array_filter(mpull($page, 'getFragmentPHID'));
if ($fragment_phids) {
$fragments = id(new PhabricatorObjectQuery())
->setViewer($this->getViewer())
->withPHIDs($fragment_phids)
->setParentQuery($this)
->execute();
$fragments = mpull($fragments, null, 'getPHID');
}
foreach ($page as $key => $version) {
$fragment_phid = $version->getFragmentPHID();
if (empty($fragments[$fragment_phid])) {
unset($page[$key]);
continue;
}
$version->attachFragment($fragments[$fragment_phid]);
}
return $page;
}
public function getQueryApplicationClass() {
return 'PhabricatorPhragmentApplication';
}
}
diff --git a/src/applications/phragment/query/PhragmentSnapshotChildQuery.php b/src/applications/phragment/query/PhragmentSnapshotChildQuery.php
index 5564408bdd..8f81beeabe 100644
--- a/src/applications/phragment/query/PhragmentSnapshotChildQuery.php
+++ b/src/applications/phragment/query/PhragmentSnapshotChildQuery.php
@@ -1,174 +1,174 @@
<?php
final class PhragmentSnapshotChildQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
private $ids;
private $snapshotPHIDs;
private $fragmentPHIDs;
private $fragmentVersionPHIDs;
private $needFragments;
private $needFragmentVersions;
public function withIDs(array $ids) {
$this->ids = $ids;
return $this;
}
public function withSnapshotPHIDs(array $snapshot_phids) {
$this->snapshotPHIDs = $snapshot_phids;
return $this;
}
public function withFragmentPHIDs(array $fragment_phids) {
$this->fragmentPHIDs = $fragment_phids;
return $this;
}
public function withFragmentVersionPHIDs(array $fragment_version_phids) {
$this->fragmentVersionPHIDs = $fragment_version_phids;
return $this;
}
public function needFragments($need_fragments) {
$this->needFragments = $need_fragments;
return $this;
}
public function needFragmentVersions($need_fragment_versions) {
$this->needFragmentVersions = $need_fragment_versions;
return $this;
}
- public function loadPage() {
+ protected function loadPage() {
$table = new PhragmentSnapshotChild();
$conn_r = $table->establishConnection('r');
$data = queryfx_all(
$conn_r,
'SELECT * FROM %T %Q %Q %Q',
$table->getTableName(),
$this->buildWhereClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
return $table->loadAllFromArray($data);
}
protected function buildWhereClause($conn_r) {
$where = array();
if ($this->ids) {
$where[] = qsprintf(
$conn_r,
'id IN (%Ld)',
$this->ids);
}
if ($this->snapshotPHIDs) {
$where[] = qsprintf(
$conn_r,
'snapshotPHID IN (%Ls)',
$this->snapshotPHIDs);
}
if ($this->fragmentPHIDs) {
$where[] = qsprintf(
$conn_r,
'fragmentPHID IN (%Ls)',
$this->fragmentPHIDs);
}
if ($this->fragmentVersionPHIDs) {
$where[] = qsprintf(
$conn_r,
'fragmentVersionPHID IN (%Ls)',
$this->fragmentVersionPHIDs);
}
$where[] = $this->buildPagingClause($conn_r);
return $this->formatWhereClause($where);
}
protected function willFilterPage(array $page) {
$snapshots = array();
$snapshot_phids = array_filter(mpull($page, 'getSnapshotPHID'));
if ($snapshot_phids) {
$snapshots = id(new PhabricatorObjectQuery())
->setViewer($this->getViewer())
->withPHIDs($snapshot_phids)
->setParentQuery($this)
->execute();
$snapshots = mpull($snapshots, null, 'getPHID');
}
foreach ($page as $key => $child) {
$snapshot_phid = $child->getSnapshotPHID();
if (empty($snapshots[$snapshot_phid])) {
unset($page[$key]);
continue;
}
$child->attachSnapshot($snapshots[$snapshot_phid]);
}
return $page;
}
protected function didFilterPage(array $page) {
if ($this->needFragments) {
$fragments = array();
$fragment_phids = array_filter(mpull($page, 'getFragmentPHID'));
if ($fragment_phids) {
$fragments = id(new PhabricatorObjectQuery())
->setViewer($this->getViewer())
->withPHIDs($fragment_phids)
->setParentQuery($this)
->execute();
$fragments = mpull($fragments, null, 'getPHID');
}
foreach ($page as $key => $child) {
$fragment_phid = $child->getFragmentPHID();
if (empty($fragments[$fragment_phid])) {
unset($page[$key]);
continue;
}
$child->attachFragment($fragments[$fragment_phid]);
}
}
if ($this->needFragmentVersions) {
$fragment_versions = array();
$fragment_version_phids = array_filter(mpull(
$page,
'getFragmentVersionPHID'));
if ($fragment_version_phids) {
$fragment_versions = id(new PhabricatorObjectQuery())
->setViewer($this->getViewer())
->withPHIDs($fragment_version_phids)
->setParentQuery($this)
->execute();
$fragment_versions = mpull($fragment_versions, null, 'getPHID');
}
foreach ($page as $key => $child) {
$fragment_version_phid = $child->getFragmentVersionPHID();
if (empty($fragment_versions[$fragment_version_phid])) {
continue;
}
$child->attachFragmentVersion(
$fragment_versions[$fragment_version_phid]);
}
}
return $page;
}
public function getQueryApplicationClass() {
return 'PhabricatorPhragmentApplication';
}
}
diff --git a/src/applications/phragment/query/PhragmentSnapshotQuery.php b/src/applications/phragment/query/PhragmentSnapshotQuery.php
index f68e16d1df..81c73441d2 100644
--- a/src/applications/phragment/query/PhragmentSnapshotQuery.php
+++ b/src/applications/phragment/query/PhragmentSnapshotQuery.php
@@ -1,111 +1,111 @@
<?php
final class PhragmentSnapshotQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
private $ids;
private $phids;
private $primaryFragmentPHIDs;
private $names;
public function withIDs(array $ids) {
$this->ids = $ids;
return $this;
}
public function withPHIDs(array $phids) {
$this->phids = $phids;
return $this;
}
public function withPrimaryFragmentPHIDs(array $primary_fragment_phids) {
$this->primaryFragmentPHIDs = $primary_fragment_phids;
return $this;
}
public function withNames(array $names) {
$this->names = $names;
return $this;
}
- public function loadPage() {
+ protected function loadPage() {
$table = new PhragmentSnapshot();
$conn_r = $table->establishConnection('r');
$data = queryfx_all(
$conn_r,
'SELECT * FROM %T %Q %Q %Q',
$table->getTableName(),
$this->buildWhereClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
return $table->loadAllFromArray($data);
}
protected function buildWhereClause($conn_r) {
$where = array();
if ($this->ids) {
$where[] = qsprintf(
$conn_r,
'id IN (%Ld)',
$this->ids);
}
if ($this->phids) {
$where[] = qsprintf(
$conn_r,
'phid IN (%Ls)',
$this->phids);
}
if ($this->primaryFragmentPHIDs) {
$where[] = qsprintf(
$conn_r,
'primaryFragmentPHID IN (%Ls)',
$this->primaryFragmentPHIDs);
}
if ($this->names) {
$where[] = qsprintf(
$conn_r,
'name IN (%Ls)',
$this->names);
}
$where[] = $this->buildPagingClause($conn_r);
return $this->formatWhereClause($where);
}
protected function willFilterPage(array $page) {
$fragments = array();
$fragment_phids = array_filter(mpull($page, 'getPrimaryFragmentPHID'));
if ($fragment_phids) {
$fragments = id(new PhabricatorObjectQuery())
->setViewer($this->getViewer())
->withPHIDs($fragment_phids)
->setParentQuery($this)
->execute();
$fragments = mpull($fragments, null, 'getPHID');
}
foreach ($page as $key => $snapshot) {
$fragment_phid = $snapshot->getPrimaryFragmentPHID();
if (empty($fragments[$fragment_phid])) {
unset($page[$key]);
continue;
}
$snapshot->attachPrimaryFragment($fragments[$fragment_phid]);
}
return $page;
}
public function getQueryApplicationClass() {
return 'PhabricatorPhragmentApplication';
}
}
diff --git a/src/applications/policy/__tests__/PhabricatorPolicyAwareTestQuery.php b/src/applications/policy/__tests__/PhabricatorPolicyAwareTestQuery.php
index dc6fc09f35..dcb2509890 100644
--- a/src/applications/policy/__tests__/PhabricatorPolicyAwareTestQuery.php
+++ b/src/applications/policy/__tests__/PhabricatorPolicyAwareTestQuery.php
@@ -1,40 +1,40 @@
<?php
/**
* Configurable test query for implementing Policy unit tests.
*/
final class PhabricatorPolicyAwareTestQuery
extends PhabricatorPolicyAwareQuery {
private $results;
private $offset = 0;
public function setResults(array $results) {
$this->results = $results;
return $this;
}
protected function willExecute() {
$this->offset = 0;
}
protected function loadPage() {
if ($this->getRawResultLimit()) {
return array_slice(
$this->results,
$this->offset,
$this->getRawResultLimit());
} else {
return array_slice($this->results, $this->offset);
}
}
- public function nextPage(array $page) {
+ protected function nextPage(array $page) {
$this->offset += count($page);
}
public function getQueryApplicationClass() {
return null;
}
}
diff --git a/src/applications/policy/query/PhabricatorPolicyQuery.php b/src/applications/policy/query/PhabricatorPolicyQuery.php
index 5ba4fbc877..01e2e2beab 100644
--- a/src/applications/policy/query/PhabricatorPolicyQuery.php
+++ b/src/applications/policy/query/PhabricatorPolicyQuery.php
@@ -1,235 +1,235 @@
<?php
final class PhabricatorPolicyQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
private $object;
private $phids;
public function setObject(PhabricatorPolicyInterface $object) {
$this->object = $object;
return $this;
}
public function withPHIDs(array $phids) {
$this->phids = $phids;
return $this;
}
public static function loadPolicies(
PhabricatorUser $viewer,
PhabricatorPolicyInterface $object) {
$results = array();
$map = array();
foreach ($object->getCapabilities() as $capability) {
$map[$capability] = $object->getPolicy($capability);
}
$policies = id(new PhabricatorPolicyQuery())
->setViewer($viewer)
->withPHIDs($map)
->execute();
foreach ($map as $capability => $phid) {
$results[$capability] = $policies[$phid];
}
return $results;
}
public static function renderPolicyDescriptions(
PhabricatorUser $viewer,
PhabricatorPolicyInterface $object,
$icon = false) {
$policies = self::loadPolicies($viewer, $object);
foreach ($policies as $capability => $policy) {
$policies[$capability] = $policy->renderDescription($icon);
}
return $policies;
}
- public function loadPage() {
+ protected function loadPage() {
if ($this->object && $this->phids) {
throw new Exception(
'You can not issue a policy query with both setObject() and '.
'setPHIDs().');
} else if ($this->object) {
$phids = $this->loadObjectPolicyPHIDs();
} else {
$phids = $this->phids;
}
$phids = array_fuse($phids);
$results = array();
// First, load global policies.
foreach ($this->getGlobalPolicies() as $phid => $policy) {
if (isset($phids[$phid])) {
$results[$phid] = $policy;
unset($phids[$phid]);
}
}
// If we still need policies, we're going to have to fetch data. Bucket
// the remaining policies into rule-based policies and handle-based
// policies.
if ($phids) {
$rule_policies = array();
$handle_policies = array();
foreach ($phids as $phid) {
$phid_type = phid_get_type($phid);
if ($phid_type == PhabricatorPolicyPHIDTypePolicy::TYPECONST) {
$rule_policies[$phid] = $phid;
} else {
$handle_policies[$phid] = $phid;
}
}
if ($handle_policies) {
$handles = id(new PhabricatorHandleQuery())
->setViewer($this->getViewer())
->withPHIDs($handle_policies)
->execute();
foreach ($handle_policies as $phid) {
$results[$phid] = PhabricatorPolicy::newFromPolicyAndHandle(
$phid,
$handles[$phid]);
}
}
if ($rule_policies) {
$rules = id(new PhabricatorPolicy())->loadAllWhere(
'phid IN (%Ls)',
$rule_policies);
$results += mpull($rules, null, 'getPHID');
}
}
$results = msort($results, 'getSortKey');
return $results;
}
public static function isGlobalPolicy($policy) {
$global_policies = self::getGlobalPolicies();
if (isset($global_policies[$policy])) {
return true;
}
return false;
}
public static function getGlobalPolicy($policy) {
if (!self::isGlobalPolicy($policy)) {
throw new Exception("Policy '{$policy}' is not a global policy!");
}
return idx(self::getGlobalPolicies(), $policy);
}
private static function getGlobalPolicies() {
static $constants = array(
PhabricatorPolicies::POLICY_PUBLIC,
PhabricatorPolicies::POLICY_USER,
PhabricatorPolicies::POLICY_ADMIN,
PhabricatorPolicies::POLICY_NOONE,
);
$results = array();
foreach ($constants as $constant) {
$results[$constant] = id(new PhabricatorPolicy())
->setType(PhabricatorPolicyType::TYPE_GLOBAL)
->setPHID($constant)
->setName(self::getGlobalPolicyName($constant))
->setShortName(self::getGlobalPolicyShortName($constant))
->makeEphemeral();
}
return $results;
}
private static function getGlobalPolicyName($policy) {
switch ($policy) {
case PhabricatorPolicies::POLICY_PUBLIC:
return pht('Public (No Login Required)');
case PhabricatorPolicies::POLICY_USER:
return pht('All Users');
case PhabricatorPolicies::POLICY_ADMIN:
return pht('Administrators');
case PhabricatorPolicies::POLICY_NOONE:
return pht('No One');
default:
return pht('Unknown Policy');
}
}
private static function getGlobalPolicyShortName($policy) {
switch ($policy) {
case PhabricatorPolicies::POLICY_PUBLIC:
return pht('Public');
default:
return null;
}
}
private function loadObjectPolicyPHIDs() {
$phids = array();
$viewer = $this->getViewer();
if ($viewer->getPHID()) {
$projects = id(new PhabricatorProjectQuery())
->setViewer($viewer)
->withMemberPHIDs(array($viewer->getPHID()))
->execute();
foreach ($projects as $project) {
$phids[] = $project->getPHID();
}
// Include the "current viewer" policy. This improves consistency, but
// is also useful for creating private instances of normally-shared object
// types, like repositories.
$phids[] = $viewer->getPHID();
}
$capabilities = $this->object->getCapabilities();
foreach ($capabilities as $capability) {
$policy = $this->object->getPolicy($capability);
if (!$policy) {
continue;
}
$phids[] = $policy;
}
// If this install doesn't have "Public" enabled, don't include it as an
// option unless the object already has a "Public" policy. In this case we
// retain the policy but enforce it as though it was "All Users".
$show_public = PhabricatorEnv::getEnvConfig('policy.allow-public');
foreach ($this->getGlobalPolicies() as $phid => $policy) {
if ($phid == PhabricatorPolicies::POLICY_PUBLIC) {
if (!$show_public) {
continue;
}
}
$phids[] = $phid;
}
return $phids;
}
protected function shouldDisablePolicyFiltering() {
// Policy filtering of policies is currently perilous and not required by
// the application.
return true;
}
public function getQueryApplicationClass() {
return 'PhabricatorPolicyApplication';
}
}
diff --git a/src/applications/ponder/query/PonderAnswerQuery.php b/src/applications/ponder/query/PonderAnswerQuery.php
index f52896a530..cea74d55d5 100644
--- a/src/applications/ponder/query/PonderAnswerQuery.php
+++ b/src/applications/ponder/query/PonderAnswerQuery.php
@@ -1,129 +1,129 @@
<?php
final class PonderAnswerQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
private $ids;
private $phids;
private $authorPHIDs;
private $questionIDs;
private $needViewerVotes;
public function withIDs(array $ids) {
$this->ids = $ids;
return $this;
}
public function withPHIDs(array $phids) {
$this->phids = $phids;
return $this;
}
public function withAuthorPHIDs(array $phids) {
$this->authorPHIDs = $phids;
return $this;
}
public function withQuestionIDs(array $ids) {
$this->questionIDs = $ids;
return $this;
}
public function needViewerVotes($need_viewer_votes) {
$this->needViewerVotes = $need_viewer_votes;
return $this;
}
private function buildWhereClause($conn_r) {
$where = array();
if ($this->ids) {
$where[] = qsprintf(
$conn_r,
'id IN (%Ld)',
$this->ids);
}
if ($this->phids) {
$where[] = qsprintf(
$conn_r,
'phid IN (%Ls)',
$this->phids);
}
if ($this->authorPHIDs) {
$where[] = qsprintf(
$conn_r,
'authorPHID IN (%Ls)',
$this->authorPHIDs);
}
$where[] = $this->buildPagingClause($conn_r);
return $this->formatWhereClause($where);
}
- public function loadPage() {
+ protected function loadPage() {
$answer = new PonderAnswer();
$conn_r = $answer->establishConnection('r');
$data = queryfx_all(
$conn_r,
'SELECT a.* FROM %T a %Q %Q %Q',
$answer->getTableName(),
$this->buildWhereClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
return $answer->loadAllFromArray($data);
}
- public function willFilterPage(array $answers) {
+ protected function willFilterPage(array $answers) {
$questions = id(new PonderQuestionQuery())
->setViewer($this->getViewer())
->withIDs(mpull($answers, 'getQuestionID'))
->execute();
foreach ($answers as $key => $answer) {
$question = idx($questions, $answer->getQuestionID());
if (!$question) {
unset($answers[$key]);
continue;
}
$answer->attachQuestion($question);
}
if ($this->needViewerVotes) {
$viewer_phid = $this->getViewer()->getPHID();
$etype = PonderAnswerHasVotingUserEdgeType::EDGECONST;
$edges = id(new PhabricatorEdgeQuery())
->withSourcePHIDs(mpull($answers, 'getPHID'))
->withDestinationPHIDs(array($viewer_phid))
->withEdgeTypes(array($etype))
->needEdgeData(true)
->execute();
foreach ($answers as $answer) {
$user_edge = idx(
$edges[$answer->getPHID()][$etype],
$viewer_phid,
array());
$answer->attachUserVote($viewer_phid, idx($user_edge, 'data', 0));
}
}
return $answers;
}
protected function getReversePaging() {
return true;
}
public function getQueryApplicationClass() {
return 'PhabricatorPonderApplication';
}
}
diff --git a/src/applications/ponder/query/PonderQuestionQuery.php b/src/applications/ponder/query/PonderQuestionQuery.php
index 4680393476..2b5bda369d 100644
--- a/src/applications/ponder/query/PonderQuestionQuery.php
+++ b/src/applications/ponder/query/PonderQuestionQuery.php
@@ -1,201 +1,201 @@
<?php
final class PonderQuestionQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
const ORDER_CREATED = 'order-created';
const ORDER_HOTTEST = 'order-hottest';
private $ids;
private $phids;
private $authorPHIDs;
private $answererPHIDs;
private $order = self::ORDER_CREATED;
private $status = 'status-any';
const STATUS_ANY = 'status-any';
const STATUS_OPEN = 'status-open';
const STATUS_CLOSED = 'status-closed';
private $needAnswers;
private $needViewerVotes;
public function withIDs(array $ids) {
$this->ids = $ids;
return $this;
}
public function withPHIDs(array $phids) {
$this->phids = $phids;
return $this;
}
public function withAuthorPHIDs(array $phids) {
$this->authorPHIDs = $phids;
return $this;
}
public function withStatus($status) {
$this->status = $status;
return $this;
}
public function withAnswererPHIDs(array $phids) {
$this->answererPHIDs = $phids;
return $this;
}
public function needAnswers($need_answers) {
$this->needAnswers = $need_answers;
return $this;
}
public function needViewerVotes($need_viewer_votes) {
$this->needViewerVotes = $need_viewer_votes;
return $this;
}
public function setOrder($order) {
$this->order = $order;
return $this;
}
private function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();
if ($this->ids) {
$where[] = qsprintf(
$conn_r,
'q.id IN (%Ld)',
$this->ids);
}
if ($this->phids) {
$where[] = qsprintf(
$conn_r,
'q.phid IN (%Ls)',
$this->phids);
}
if ($this->authorPHIDs) {
$where[] = qsprintf(
$conn_r,
'q.authorPHID IN (%Ls)',
$this->authorPHIDs);
}
if ($this->status) {
switch ($this->status) {
case self::STATUS_ANY:
break;
case self::STATUS_OPEN:
$where[] = qsprintf(
$conn_r,
'q.status = %d',
PonderQuestionStatus::STATUS_OPEN);
break;
case self::STATUS_CLOSED:
$where[] = qsprintf(
$conn_r,
'q.status = %d',
PonderQuestionStatus::STATUS_CLOSED);
break;
default:
throw new Exception("Unknown status query '{$this->status}'!");
}
}
$where[] = $this->buildPagingClause($conn_r);
return $this->formatWhereClause($where);
}
private function buildOrderByClause(AphrontDatabaseConnection $conn_r) {
switch ($this->order) {
case self::ORDER_HOTTEST:
return qsprintf($conn_r, 'ORDER BY q.heat DESC, q.id DESC');
case self::ORDER_CREATED:
return qsprintf($conn_r, 'ORDER BY q.id DESC');
default:
throw new Exception("Unknown order '{$this->order}'!");
}
}
protected function loadPage() {
$question = new PonderQuestion();
$conn_r = $question->establishConnection('r');
$data = queryfx_all(
$conn_r,
'SELECT q.* FROM %T q %Q %Q %Q %Q',
$question->getTableName(),
$this->buildJoinsClause($conn_r),
$this->buildWhereClause($conn_r),
$this->buildOrderByClause($conn_r),
$this->buildLimitClause($conn_r));
return $question->loadAllFromArray($data);
}
- public function willFilterPage(array $questions) {
+ protected function willFilterPage(array $questions) {
if ($this->needAnswers) {
$aquery = id(new PonderAnswerQuery())
->setViewer($this->getViewer())
->withQuestionIDs(mpull($questions, 'getID'));
if ($this->needViewerVotes) {
$aquery->needViewerVotes($this->needViewerVotes);
}
$answers = $aquery->execute();
$answers = mgroup($answers, 'getQuestionID');
foreach ($questions as $question) {
$question_answers = idx($answers, $question->getID(), array());
$question->attachAnswers(mpull($question_answers, null, 'getPHID'));
}
}
if ($this->needViewerVotes) {
$viewer_phid = $this->getViewer()->getPHID();
$etype = PonderQuestionHasVotingUserEdgeType::EDGECONST;
$edges = id(new PhabricatorEdgeQuery())
->withSourcePHIDs(mpull($questions, 'getPHID'))
->withDestinationPHIDs(array($viewer_phid))
->withEdgeTypes(array($etype))
->needEdgeData(true)
->execute();
foreach ($questions as $question) {
$user_edge = idx(
$edges[$question->getPHID()][$etype],
$viewer_phid,
array());
$question->attachUserVote($viewer_phid, idx($user_edge, 'data', 0));
}
}
return $questions;
}
private function buildJoinsClause(AphrontDatabaseConnection $conn_r) {
$joins = array();
if ($this->answererPHIDs) {
$answer_table = new PonderAnswer();
$joins[] = qsprintf(
$conn_r,
'JOIN %T a ON a.questionID = q.id AND a.authorPHID IN (%Ls)',
$answer_table->getTableName(),
$this->answererPHIDs);
}
return implode(' ', $joins);
}
public function getQueryApplicationClass() {
return 'PhabricatorPonderApplication';
}
}
diff --git a/src/applications/releeph/query/ReleephBranchQuery.php b/src/applications/releeph/query/ReleephBranchQuery.php
index 0dabec85f3..43a600fa2d 100644
--- a/src/applications/releeph/query/ReleephBranchQuery.php
+++ b/src/applications/releeph/query/ReleephBranchQuery.php
@@ -1,152 +1,152 @@
<?php
final class ReleephBranchQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
private $ids;
private $phids;
private $productPHIDs;
private $productIDs;
const STATUS_ALL = 'status-all';
const STATUS_OPEN = 'status-open';
private $status = self::STATUS_ALL;
private $needCutPointCommits;
public function withIDs(array $ids) {
$this->ids = $ids;
return $this;
}
public function withPHIDs(array $phids) {
$this->phids = $phids;
return $this;
}
public function needCutPointCommits($need_commits) {
$this->needCutPointCommits = $need_commits;
return $this;
}
public function withStatus($status) {
$this->status = $status;
return $this;
}
public function withProductPHIDs($product_phids) {
$this->productPHIDs = $product_phids;
return $this;
}
- public function loadPage() {
+ protected function loadPage() {
$table = new ReleephBranch();
$conn_r = $table->establishConnection('r');
$data = queryfx_all(
$conn_r,
'SELECT * FROM %T %Q %Q %Q',
$table->getTableName(),
$this->buildWhereClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
return $table->loadAllFromArray($data);
}
- public function willExecute() {
+ protected function willExecute() {
if ($this->productPHIDs !== null) {
$products = id(new ReleephProductQuery())
->setViewer($this->getViewer())
->withPHIDs($this->productPHIDs)
->execute();
if (!$products) {
throw new PhabricatorEmptyQueryException();
}
$this->productIDs = mpull($products, 'getID');
}
}
- public function willFilterPage(array $branches) {
+ protected function willFilterPage(array $branches) {
$project_ids = mpull($branches, 'getReleephProjectID');
$projects = id(new ReleephProductQuery())
->withIDs($project_ids)
->setViewer($this->getViewer())
->execute();
foreach ($branches as $key => $branch) {
$project_id = $project_ids[$key];
if (isset($projects[$project_id])) {
$branch->attachProject($projects[$project_id]);
} else {
unset($branches[$key]);
}
}
if ($this->needCutPointCommits) {
$commit_phids = mpull($branches, 'getCutPointCommitPHID');
$commits = id(new DiffusionCommitQuery())
->setViewer($this->getViewer())
->withPHIDs($commit_phids)
->execute();
$commits = mpull($commits, null, 'getPHID');
foreach ($branches as $branch) {
$commit = idx($commits, $branch->getCutPointCommitPHID());
$branch->attachCutPointCommit($commit);
}
}
return $branches;
}
private function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();
if ($this->ids !== null) {
$where[] = qsprintf(
$conn_r,
'id IN (%Ld)',
$this->ids);
}
if ($this->phids !== null) {
$where[] = qsprintf(
$conn_r,
'phid IN (%Ls)',
$this->phids);
}
if ($this->productIDs !== null) {
$where[] = qsprintf(
$conn_r,
'releephProjectID IN (%Ld)',
$this->productIDs);
}
$status = $this->status;
switch ($status) {
case self::STATUS_ALL:
break;
case self::STATUS_OPEN:
$where[] = qsprintf(
$conn_r,
'isActive = 1');
break;
default:
throw new Exception("Unknown status constant '{$status}'!");
}
$where[] = $this->buildPagingClause($conn_r);
return $this->formatWhereClause($where);
}
public function getQueryApplicationClass() {
return 'PhabricatorReleephApplication';
}
}
diff --git a/src/applications/releeph/query/ReleephProductQuery.php b/src/applications/releeph/query/ReleephProductQuery.php
index 9e826235f8..0c788811bc 100644
--- a/src/applications/releeph/query/ReleephProductQuery.php
+++ b/src/applications/releeph/query/ReleephProductQuery.php
@@ -1,173 +1,173 @@
<?php
final class ReleephProductQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
private $active;
private $ids;
private $phids;
private $repositoryPHIDs;
private $needArcanistProjects;
private $order = 'order-id';
const ORDER_ID = 'order-id';
const ORDER_NAME = 'order-name';
public function withActive($active) {
$this->active = $active;
return $this;
}
public function setOrder($order) {
$this->order = $order;
return $this;
}
public function withIDs(array $ids) {
$this->ids = $ids;
return $this;
}
public function withPHIDs(array $phids) {
$this->phids = $phids;
return $this;
}
public function withRepositoryPHIDs(array $repository_phids) {
$this->repositoryPHIDs = $repository_phids;
return $this;
}
public function needArcanistProjects($need) {
$this->needArcanistProjects = $need;
return $this;
}
- public function loadPage() {
+ protected function loadPage() {
$table = new ReleephProject();
$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));
return $table->loadAllFromArray($rows);
}
- public function willFilterPage(array $projects) {
+ protected function willFilterPage(array $projects) {
assert_instances_of($projects, 'ReleephProject');
$repository_phids = mpull($projects, 'getRepositoryPHID');
$repositories = id(new PhabricatorRepositoryQuery())
->setViewer($this->getViewer())
->withPHIDs($repository_phids)
->execute();
$repositories = mpull($repositories, null, 'getPHID');
foreach ($projects as $key => $project) {
$repo = idx($repositories, $project->getRepositoryPHID());
if (!$repo) {
unset($projects[$key]);
continue;
}
$project->attachRepository($repo);
}
return $projects;
}
- public function didFilterPage(array $products) {
+ protected function didFilterPage(array $products) {
if ($this->needArcanistProjects) {
$project_ids = array_filter(mpull($products, 'getArcanistProjectID'));
if ($project_ids) {
$projects = id(new PhabricatorRepositoryArcanistProject())
->loadAllWhere('id IN (%Ld)', $project_ids);
$projects = mpull($projects, null, 'getID');
} else {
$projects = array();
}
foreach ($products as $product) {
$project_id = $product->getArcanistProjectID();
$project = idx($projects, $project_id);
$product->attachArcanistProject($project);
}
}
return $products;
}
private function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();
if ($this->active !== null) {
$where[] = qsprintf(
$conn_r,
'isActive = %d',
(int)$this->active);
}
if ($this->ids !== null) {
$where[] = qsprintf(
$conn_r,
'id IN (%Ls)',
$this->ids);
}
if ($this->phids !== null) {
$where[] = qsprintf(
$conn_r,
'phid IN (%Ls)',
$this->phids);
}
if ($this->repositoryPHIDs !== null) {
$where[] = qsprintf(
$conn_r,
'repositoryPHID IN (%Ls)',
$this->repositoryPHIDs);
}
$where[] = $this->buildPagingClause($conn_r);
return $this->formatWhereClause($where);
}
protected function getReversePaging() {
switch ($this->order) {
case self::ORDER_NAME:
return true;
}
return parent::getReversePaging();
}
protected function getPagingValue($result) {
switch ($this->order) {
case self::ORDER_NAME:
return $result->getName();
}
return parent::getPagingValue();
}
protected function getPagingColumn() {
switch ($this->order) {
case self::ORDER_NAME:
return 'name';
case self::ORDER_ID:
return parent::getPagingColumn();
default:
throw new Exception("Uknown order '{$this->order}'!");
}
}
public function getQueryApplicationClass() {
return 'PhabricatorReleephApplication';
}
}
diff --git a/src/applications/releeph/query/ReleephRequestQuery.php b/src/applications/releeph/query/ReleephRequestQuery.php
index 41ea0f6954..84d35d288a 100644
--- a/src/applications/releeph/query/ReleephRequestQuery.php
+++ b/src/applications/releeph/query/ReleephRequestQuery.php
@@ -1,247 +1,247 @@
<?php
final class ReleephRequestQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
private $requestedCommitPHIDs;
private $ids;
private $phids;
private $severities;
private $requestorPHIDs;
private $branchIDs;
private $requestedObjectPHIDs;
const STATUS_ALL = 'status-all';
const STATUS_OPEN = 'status-open';
const STATUS_REQUESTED = 'status-requested';
const STATUS_NEEDS_PULL = 'status-needs-pull';
const STATUS_REJECTED = 'status-rejected';
const STATUS_ABANDONED = 'status-abandoned';
const STATUS_PULLED = 'status-pulled';
const STATUS_NEEDS_REVERT = 'status-needs-revert';
const STATUS_REVERTED = 'status-reverted';
private $status = self::STATUS_ALL;
public function withIDs(array $ids) {
$this->ids = $ids;
return $this;
}
public function withPHIDs(array $phids) {
$this->phids = $phids;
return $this;
}
public function withBranchIDs(array $branch_ids) {
$this->branchIDs = $branch_ids;
return $this;
}
public function withStatus($status) {
$this->status = $status;
return $this;
}
public function withRequestedCommitPHIDs(array $requested_commit_phids) {
$this->requestedCommitPHIDs = $requested_commit_phids;
return $this;
}
public function withRequestorPHIDs(array $phids) {
$this->requestorPHIDs = $phids;
return $this;
}
public function withSeverities(array $severities) {
$this->severities = $severities;
return $this;
}
public function withRequestedObjectPHIDs(array $phids) {
$this->requestedObjectPHIDs = $phids;
return $this;
}
- public function loadPage() {
+ protected function loadPage() {
$table = new ReleephRequest();
$conn_r = $table->establishConnection('r');
$data = queryfx_all(
$conn_r,
'SELECT * FROM %T %Q %Q %Q',
$table->getTableName(),
$this->buildWhereClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
return $table->loadAllFromArray($data);
}
- public function willFilterPage(array $requests) {
+ protected function willFilterPage(array $requests) {
// Load requested objects: you must be able to see an object to see
// requests for it.
$object_phids = mpull($requests, 'getRequestedObjectPHID');
$objects = id(new PhabricatorObjectQuery())
->setViewer($this->getViewer())
->setParentQuery($this)
->withPHIDs($object_phids)
->execute();
foreach ($requests as $key => $request) {
$object_phid = $request->getRequestedObjectPHID();
$object = idx($objects, $object_phid);
if (!$object) {
unset($requests[$key]);
continue;
}
$request->attachRequestedObject($object);
}
if ($this->severities) {
$severities = array_fuse($this->severities);
foreach ($requests as $key => $request) {
// NOTE: Facebook uses a custom field here.
if (ReleephDefaultFieldSelector::isFacebook()) {
$severity = $request->getDetail('severity');
} else {
$severity = $request->getDetail('releeph:severity');
}
if (empty($severities[$severity])) {
unset($requests[$key]);
}
}
}
$branch_ids = array_unique(mpull($requests, 'getBranchID'));
$branches = id(new ReleephBranchQuery())
->withIDs($branch_ids)
->setViewer($this->getViewer())
->execute();
$branches = mpull($branches, null, 'getID');
foreach ($requests as $key => $request) {
$branch = idx($branches, $request->getBranchID());
if (!$branch) {
unset($requests[$key]);
continue;
}
$request->attachBranch($branch);
}
// TODO: These should be serviced by the query, but are not currently
// denormalized anywhere. For now, filter them here instead. Note that
// we must perform this filtering *after* querying and attaching branches,
// because request status depends on the product.
$keep_status = array_fuse($this->getKeepStatusConstants());
if ($keep_status) {
foreach ($requests as $key => $request) {
if (empty($keep_status[$request->getStatus()])) {
unset($requests[$key]);
}
}
}
return $requests;
}
private function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();
if ($this->ids !== null) {
$where[] = qsprintf(
$conn_r,
'id IN (%Ld)',
$this->ids);
}
if ($this->phids !== null) {
$where[] = qsprintf(
$conn_r,
'phid IN (%Ls)',
$this->phids);
}
if ($this->branchIDs !== null) {
$where[] = qsprintf(
$conn_r,
'branchID IN (%Ld)',
$this->branchIDs);
}
if ($this->requestedCommitPHIDs !== null) {
$where[] = qsprintf(
$conn_r,
'requestCommitPHID IN (%Ls)',
$this->requestedCommitPHIDs);
}
if ($this->requestorPHIDs !== null) {
$where[] = qsprintf(
$conn_r,
'requestUserPHID IN (%Ls)',
$this->requestorPHIDs);
}
if ($this->requestedObjectPHIDs !== null) {
$where[] = qsprintf(
$conn_r,
'requestedObjectPHID IN (%Ls)',
$this->requestedObjectPHIDs);
}
$where[] = $this->buildPagingClause($conn_r);
return $this->formatWhereClause($where);
}
private function getKeepStatusConstants() {
switch ($this->status) {
case self::STATUS_ALL:
return array();
case self::STATUS_OPEN:
return array(
ReleephRequestStatus::STATUS_REQUESTED,
ReleephRequestStatus::STATUS_NEEDS_PICK,
ReleephRequestStatus::STATUS_NEEDS_REVERT,
);
case self::STATUS_REQUESTED:
return array(
ReleephRequestStatus::STATUS_REQUESTED,
);
case self::STATUS_NEEDS_PULL:
return array(
ReleephRequestStatus::STATUS_NEEDS_PICK,
);
case self::STATUS_REJECTED:
return array(
ReleephRequestStatus::STATUS_REJECTED,
);
case self::STATUS_ABANDONED:
return array(
ReleephRequestStatus::STATUS_ABANDONED,
);
case self::STATUS_PULLED:
return array(
ReleephRequestStatus::STATUS_PICKED,
);
case self::STATUS_NEEDS_REVERT:
return array(
ReleephRequestStatus::NEEDS_REVERT,
);
case self::STATUS_REVERTED:
return array(
ReleephRequestStatus::REVERTED,
);
default:
throw new Exception("Unknown status '{$this->status}'!");
}
}
public function getQueryApplicationClass() {
return 'PhabricatorReleephApplication';
}
}
diff --git a/src/applications/repository/query/PhabricatorRepositoryArcanistProjectQuery.php b/src/applications/repository/query/PhabricatorRepositoryArcanistProjectQuery.php
index afed928c14..5cbc730075 100644
--- a/src/applications/repository/query/PhabricatorRepositoryArcanistProjectQuery.php
+++ b/src/applications/repository/query/PhabricatorRepositoryArcanistProjectQuery.php
@@ -1,87 +1,87 @@
<?php
final class PhabricatorRepositoryArcanistProjectQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
private $ids;
private $phids;
private $needRepositories;
public function withIDs(array $ids) {
$this->ids = $ids;
return $this;
}
public function withPHIDs(array $phids) {
$this->phids = $phids;
return $this;
}
public function needRepositories($need_repositories) {
$this->needRepositories = $need_repositories;
return $this;
}
protected function loadPage() {
$table = new PhabricatorRepositoryArcanistProject();
$conn_r = $table->establishConnection('r');
$data = queryfx_all(
$conn_r,
'SELECT * FROM %T %Q %Q %Q',
$table->getTableName(),
$this->buildWhereClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
return $table->loadAllFromArray($data);
}
- public function willFilterPage(array $projects) {
+ protected function willFilterPage(array $projects) {
assert_instances_of($projects, 'PhabricatorRepositoryArcanistProject');
if ($this->needRepositories) {
$repository_ids = mpull($projects, 'getRepositoryID');
$repositories = id(new PhabricatorRepositoryQuery())
->setViewer($this->getViewer())
->withIDs($repository_ids)
->execute();
foreach ($projects as $project) {
$repo = idx($repositories, $project->getRepositoryID());
$project->attachRepository($repo);
}
}
return $projects;
}
private function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();
if ($this->ids) {
$where[] = qsprintf(
$conn_r,
'id IN (%Ld)',
$this->ids);
}
if ($this->phids) {
$where[] = qsprintf(
$conn_r,
'phid IN (%Ls)',
$this->phids);
}
$where[] = $this->buildPagingClause($conn_r);
return $this->formatWhereClause($where);
}
public function getQueryApplicationClass() {
// TODO: Diffusion? Differential?
return null;
}
}
diff --git a/src/applications/repository/query/PhabricatorRepositoryMirrorQuery.php b/src/applications/repository/query/PhabricatorRepositoryMirrorQuery.php
index 160c6cacb4..f6e7d22950 100644
--- a/src/applications/repository/query/PhabricatorRepositoryMirrorQuery.php
+++ b/src/applications/repository/query/PhabricatorRepositoryMirrorQuery.php
@@ -1,99 +1,99 @@
<?php
final class PhabricatorRepositoryMirrorQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
private $ids;
private $phids;
private $repositoryPHIDs;
public function withIDs(array $ids) {
$this->ids = $ids;
return $this;
}
public function withPHIDs(array $phids) {
$this->phids = $phids;
return $this;
}
public function withRepositoryPHIDs(array $repository_phids) {
$this->repositoryPHIDs = $repository_phids;
return $this;
}
protected function loadPage() {
$table = new PhabricatorRepositoryMirror();
$conn_r = $table->establishConnection('r');
$data = queryfx_all(
$conn_r,
'SELECT * FROM %T %Q %Q %Q',
$table->getTableName(),
$this->buildWhereClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
return $table->loadAllFromArray($data);
}
- public function willFilterPage(array $mirrors) {
+ protected function willFilterPage(array $mirrors) {
assert_instances_of($mirrors, 'PhabricatorRepositoryMirror');
$repository_phids = mpull($mirrors, 'getRepositoryPHID');
if ($repository_phids) {
$repositories = id(new PhabricatorRepositoryQuery())
->setViewer($this->getViewer())
->withPHIDs($repository_phids)
->execute();
$repositories = mpull($repositories, null, 'getPHID');
} else {
$repositories = array();
}
foreach ($mirrors as $key => $mirror) {
$phid = $mirror->getRepositoryPHID();
if (empty($repositories[$phid])) {
unset($mirrors[$key]);
continue;
}
$mirror->attachRepository($repositories[$phid]);
}
return $mirrors;
}
private function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();
if ($this->ids) {
$where[] = qsprintf(
$conn_r,
'id IN (%Ld)',
$this->ids);
}
if ($this->phids) {
$where[] = qsprintf(
$conn_r,
'phid IN (%Ls)',
$this->phids);
}
if ($this->repositoryPHIDs) {
$where[] = qsprintf(
$conn_r,
'repositoryPHID IN (%Ls)',
$this->repositoryPHIDs);
}
$where[] = $this->buildPagingClause($conn_r);
return $this->formatWhereClause($where);
}
public function getQueryApplicationClass() {
return 'PhabricatorDiffusionApplication';
}
}
diff --git a/src/applications/repository/query/PhabricatorRepositoryPushEventQuery.php b/src/applications/repository/query/PhabricatorRepositoryPushEventQuery.php
index 9f3a8c0863..14b4e4d596 100644
--- a/src/applications/repository/query/PhabricatorRepositoryPushEventQuery.php
+++ b/src/applications/repository/query/PhabricatorRepositoryPushEventQuery.php
@@ -1,131 +1,131 @@
<?php
final class PhabricatorRepositoryPushEventQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
private $ids;
private $phids;
private $repositoryPHIDs;
private $pusherPHIDs;
private $needLogs;
public function withIDs(array $ids) {
$this->ids = $ids;
return $this;
}
public function withPHIDs(array $phids) {
$this->phids = $phids;
return $this;
}
public function withRepositoryPHIDs(array $repository_phids) {
$this->repositoryPHIDs = $repository_phids;
return $this;
}
public function withPusherPHIDs(array $pusher_phids) {
$this->pusherPHIDs = $pusher_phids;
return $this;
}
public function needLogs($need_logs) {
$this->needLogs = $need_logs;
return $this;
}
protected function loadPage() {
$table = new PhabricatorRepositoryPushEvent();
$conn_r = $table->establishConnection('r');
$data = queryfx_all(
$conn_r,
'SELECT * FROM %T %Q %Q %Q',
$table->getTableName(),
$this->buildWhereClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
return $table->loadAllFromArray($data);
}
- public function willFilterPage(array $events) {
+ protected function willFilterPage(array $events) {
$repository_phids = mpull($events, 'getRepositoryPHID');
$repositories = id(new PhabricatorRepositoryQuery())
->setViewer($this->getViewer())
->withPHIDs($repository_phids)
->execute();
$repositories = mpull($repositories, null, 'getPHID');
foreach ($events as $key => $event) {
$phid = $event->getRepositoryPHID();
if (empty($repositories[$phid])) {
unset($events[$key]);
continue;
}
$event->attachRepository($repositories[$phid]);
}
return $events;
}
- public function didFilterPage(array $events) {
+ protected function didFilterPage(array $events) {
$phids = mpull($events, 'getPHID');
if ($this->needLogs) {
$logs = id(new PhabricatorRepositoryPushLogQuery())
->setParentQuery($this)
->setViewer($this->getViewer())
->withPushEventPHIDs($phids)
->execute();
$logs = mgroup($logs, 'getPushEventPHID');
foreach ($events as $key => $event) {
$event_logs = idx($logs, $event->getPHID(), array());
$event->attachLogs($event_logs);
}
}
return $events;
}
private function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();
if ($this->ids) {
$where[] = qsprintf(
$conn_r,
'id IN (%Ld)',
$this->ids);
}
if ($this->phids) {
$where[] = qsprintf(
$conn_r,
'phid IN (%Ls)',
$this->phids);
}
if ($this->repositoryPHIDs) {
$where[] = qsprintf(
$conn_r,
'repositoryPHID IN (%Ls)',
$this->repositoryPHIDs);
}
if ($this->pusherPHIDs) {
$where[] = qsprintf(
$conn_r,
'pusherPHID in (%Ls)',
$this->pusherPHIDs);
}
$where[] = $this->buildPagingClause($conn_r);
return $this->formatWhereClause($where);
}
public function getQueryApplicationClass() {
return 'PhabricatorDiffusionApplication';
}
}
diff --git a/src/applications/repository/query/PhabricatorRepositoryPushLogQuery.php b/src/applications/repository/query/PhabricatorRepositoryPushLogQuery.php
index d76ee930e4..7812f77abd 100644
--- a/src/applications/repository/query/PhabricatorRepositoryPushLogQuery.php
+++ b/src/applications/repository/query/PhabricatorRepositoryPushLogQuery.php
@@ -1,146 +1,146 @@
<?php
final class PhabricatorRepositoryPushLogQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
private $ids;
private $phids;
private $repositoryPHIDs;
private $pusherPHIDs;
private $refTypes;
private $newRefs;
private $pushEventPHIDs;
public function withIDs(array $ids) {
$this->ids = $ids;
return $this;
}
public function withPHIDs(array $phids) {
$this->phids = $phids;
return $this;
}
public function withRepositoryPHIDs(array $repository_phids) {
$this->repositoryPHIDs = $repository_phids;
return $this;
}
public function withPusherPHIDs(array $pusher_phids) {
$this->pusherPHIDs = $pusher_phids;
return $this;
}
public function withRefTypes(array $ref_types) {
$this->refTypes = $ref_types;
return $this;
}
public function withNewRefs(array $new_refs) {
$this->newRefs = $new_refs;
return $this;
}
public function withPushEventPHIDs(array $phids) {
$this->pushEventPHIDs = $phids;
return $this;
}
protected function loadPage() {
$table = new PhabricatorRepositoryPushLog();
$conn_r = $table->establishConnection('r');
$data = queryfx_all(
$conn_r,
'SELECT * FROM %T %Q %Q %Q',
$table->getTableName(),
$this->buildWhereClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
return $table->loadAllFromArray($data);
}
- public function willFilterPage(array $logs) {
+ protected function willFilterPage(array $logs) {
$event_phids = mpull($logs, 'getPushEventPHID');
$events = id(new PhabricatorObjectQuery())
->setParentQuery($this)
->setViewer($this->getViewer())
->withPHIDs($event_phids)
->execute();
$events = mpull($events, null, 'getPHID');
foreach ($logs as $key => $log) {
$event = idx($events, $log->getPushEventPHID());
if (!$event) {
unset($logs[$key]);
continue;
}
$log->attachPushEvent($event);
}
return $logs;
}
private function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();
if ($this->ids) {
$where[] = qsprintf(
$conn_r,
'id IN (%Ld)',
$this->ids);
}
if ($this->phids) {
$where[] = qsprintf(
$conn_r,
'phid IN (%Ls)',
$this->phids);
}
if ($this->repositoryPHIDs) {
$where[] = qsprintf(
$conn_r,
'repositoryPHID IN (%Ls)',
$this->repositoryPHIDs);
}
if ($this->pusherPHIDs) {
$where[] = qsprintf(
$conn_r,
'pusherPHID in (%Ls)',
$this->pusherPHIDs);
}
if ($this->pushEventPHIDs) {
$where[] = qsprintf(
$conn_r,
'pushEventPHID in (%Ls)',
$this->pushEventPHIDs);
}
if ($this->refTypes) {
$where[] = qsprintf(
$conn_r,
'refType IN (%Ls)',
$this->refTypes);
}
if ($this->newRefs) {
$where[] = qsprintf(
$conn_r,
'refNew IN (%Ls)',
$this->newRefs);
}
$where[] = $this->buildPagingClause($conn_r);
return $this->formatWhereClause($where);
}
public function getQueryApplicationClass() {
return 'PhabricatorDiffusionApplication';
}
}
diff --git a/src/applications/repository/query/PhabricatorRepositoryQuery.php b/src/applications/repository/query/PhabricatorRepositoryQuery.php
index 88d71e9972..389852c000 100644
--- a/src/applications/repository/query/PhabricatorRepositoryQuery.php
+++ b/src/applications/repository/query/PhabricatorRepositoryQuery.php
@@ -1,548 +1,548 @@
<?php
final class PhabricatorRepositoryQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
private $ids;
private $phids;
private $callsigns;
private $types;
private $uuids;
private $nameContains;
private $remoteURIs;
private $anyProjectPHIDs;
private $numericIdentifiers;
private $callsignIdentifiers;
private $phidIdentifiers;
private $identifierMap;
const STATUS_OPEN = 'status-open';
const STATUS_CLOSED = 'status-closed';
const STATUS_ALL = 'status-all';
private $status = self::STATUS_ALL;
const ORDER_CREATED = 'order-created';
const ORDER_COMMITTED = 'order-committed';
const ORDER_CALLSIGN = 'order-callsign';
const ORDER_NAME = 'order-name';
private $order = self::ORDER_CREATED;
const HOSTED_PHABRICATOR = 'hosted-phab';
const HOSTED_REMOTE = 'hosted-remote';
const HOSTED_ALL = 'hosted-all';
private $hosted = self::HOSTED_ALL;
private $needMostRecentCommits;
private $needCommitCounts;
private $needProjectPHIDs;
public function withIDs(array $ids) {
$this->ids = $ids;
return $this;
}
public function withPHIDs(array $phids) {
$this->phids = $phids;
return $this;
}
public function withCallsigns(array $callsigns) {
$this->callsigns = $callsigns;
return $this;
}
public function withIdentifiers(array $identifiers) {
$ids = array(); $callsigns = array(); $phids = array();
foreach ($identifiers as $identifier) {
if (ctype_digit($identifier)) {
$ids[$identifier] = $identifier;
} else {
$repository_type = PhabricatorRepositoryRepositoryPHIDType::TYPECONST;
if (phid_get_type($identifier) === $repository_type) {
$phids[$identifier] = $identifier;
} else {
$callsigns[$identifier] = $identifier;
}
}
}
$this->numericIdentifiers = $ids;
$this->callsignIdentifiers = $callsigns;
$this->phidIdentifiers = $phids;
return $this;
}
public function withStatus($status) {
$this->status = $status;
return $this;
}
public function withHosted($hosted) {
$this->hosted = $hosted;
return $this;
}
public function withTypes(array $types) {
$this->types = $types;
return $this;
}
public function withUUIDs(array $uuids) {
$this->uuids = $uuids;
return $this;
}
public function withNameContains($contains) {
$this->nameContains = $contains;
return $this;
}
public function withRemoteURIs(array $uris) {
$this->remoteURIs = $uris;
return $this;
}
public function withAnyProjects(array $projects) {
$this->anyProjectPHIDs = $projects;
return $this;
}
public function needCommitCounts($need_counts) {
$this->needCommitCounts = $need_counts;
return $this;
}
public function needMostRecentCommits($need_commits) {
$this->needMostRecentCommits = $need_commits;
return $this;
}
public function needProjectPHIDs($need_phids) {
$this->needProjectPHIDs = $need_phids;
return $this;
}
public function setOrder($order) {
$this->order = $order;
return $this;
}
public function getIdentifierMap() {
if ($this->identifierMap === null) {
throw new Exception(
'You must execute() the query before accessing the identifier map.');
}
return $this->identifierMap;
}
protected function loadPage() {
$table = new PhabricatorRepository();
$conn_r = $table->establishConnection('r');
if ($this->identifierMap === null) {
$this->identifierMap = array();
}
$data = queryfx_all(
$conn_r,
'SELECT * FROM %T r %Q %Q %Q %Q',
$table->getTableName(),
$this->buildJoinsClause($conn_r),
$this->buildWhereClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
$repositories = $table->loadAllFromArray($data);
if ($this->needCommitCounts) {
$sizes = ipull($data, 'size', 'id');
foreach ($repositories as $id => $repository) {
$repository->attachCommitCount(nonempty($sizes[$id], 0));
}
}
if ($this->needMostRecentCommits) {
$commit_ids = ipull($data, 'lastCommitID', 'id');
$commit_ids = array_filter($commit_ids);
if ($commit_ids) {
$commits = id(new DiffusionCommitQuery())
->setViewer($this->getViewer())
->withIDs($commit_ids)
->execute();
} else {
$commits = array();
}
foreach ($repositories as $id => $repository) {
$commit = null;
if (idx($commit_ids, $id)) {
$commit = idx($commits, $commit_ids[$id]);
}
$repository->attachMostRecentCommit($commit);
}
}
return $repositories;
}
- public function willFilterPage(array $repositories) {
+ protected function willFilterPage(array $repositories) {
assert_instances_of($repositories, 'PhabricatorRepository');
// TODO: Denormalize repository status into the PhabricatorRepository
// table so we can do this filtering in the database.
foreach ($repositories as $key => $repo) {
$status = $this->status;
switch ($status) {
case self::STATUS_OPEN:
if (!$repo->isTracked()) {
unset($repositories[$key]);
}
break;
case self::STATUS_CLOSED:
if ($repo->isTracked()) {
unset($repositories[$key]);
}
break;
case self::STATUS_ALL:
break;
default:
throw new Exception("Unknown status '{$status}'!");
}
// TODO: This should also be denormalized.
$hosted = $this->hosted;
switch ($hosted) {
case self::HOSTED_PHABRICATOR:
if (!$repo->isHosted()) {
unset($repositories[$key]);
}
break;
case self::HOSTED_REMOTE:
if ($repo->isHosted()) {
unset($repositories[$key]);
}
break;
case self::HOSTED_ALL:
break;
default:
throw new Exception("Uknown hosted failed '${hosted}'!");
}
}
// TODO: Denormalize this, too.
if ($this->remoteURIs) {
$try_uris = $this->getNormalizedPaths();
$try_uris = array_fuse($try_uris);
foreach ($repositories as $key => $repository) {
if (!isset($try_uris[$repository->getNormalizedPath()])) {
unset($repositories[$key]);
}
}
}
// Build the identifierMap
if ($this->numericIdentifiers) {
foreach ($this->numericIdentifiers as $id) {
if (isset($repositories[$id])) {
$this->identifierMap[$id] = $repositories[$id];
}
}
}
if ($this->callsignIdentifiers) {
$repository_callsigns = mpull($repositories, null, 'getCallsign');
foreach ($this->callsignIdentifiers as $callsign) {
if (isset($repository_callsigns[$callsign])) {
$this->identifierMap[$callsign] = $repository_callsigns[$callsign];
}
}
}
if ($this->phidIdentifiers) {
$repository_phids = mpull($repositories, null, 'getPHID');
foreach ($this->phidIdentifiers as $phid) {
if (isset($repository_phids[$phid])) {
$this->identifierMap[$phid] = $repository_phids[$phid];
}
}
}
return $repositories;
}
- public function didFilterPage(array $repositories) {
+ protected function didFilterPage(array $repositories) {
if ($this->needProjectPHIDs) {
$type_project = PhabricatorProjectObjectHasProjectEdgeType::EDGECONST;
$edge_query = id(new PhabricatorEdgeQuery())
->withSourcePHIDs(mpull($repositories, 'getPHID'))
->withEdgeTypes(array($type_project));
$edge_query->execute();
foreach ($repositories as $repository) {
$project_phids = $edge_query->getDestinationPHIDs(
array(
$repository->getPHID(),
));
$repository->attachProjectPHIDs($project_phids);
}
}
return $repositories;
}
- public function getReversePaging() {
+ protected function getReversePaging() {
switch ($this->order) {
case self::ORDER_CALLSIGN:
case self::ORDER_NAME:
return true;
}
return false;
}
protected function getPagingColumn() {
$order = $this->order;
switch ($order) {
case self::ORDER_CREATED:
return 'r.id';
case self::ORDER_COMMITTED:
return 's.epoch';
case self::ORDER_CALLSIGN:
return 'r.callsign';
case self::ORDER_NAME:
return 'r.name';
default:
throw new Exception("Unknown order '{$order}!'");
}
}
private function loadCursorObject($id) {
$query = id(new PhabricatorRepositoryQuery())
->setViewer($this->getPagingViewer())
->withIDs(array((int)$id));
if ($this->order == self::ORDER_COMMITTED) {
$query->needMostRecentCommits(true);
}
$results = $query->execute();
return head($results);
}
protected function buildPagingClause(AphrontDatabaseConnection $conn_r) {
$default = parent::buildPagingClause($conn_r);
$before_id = $this->getBeforeID();
$after_id = $this->getAfterID();
if (!$before_id && !$after_id) {
return $default;
}
$order = $this->order;
if ($order == self::ORDER_CREATED) {
return $default;
}
if ($before_id) {
$cursor = $this->loadCursorObject($before_id);
} else {
$cursor = $this->loadCursorObject($after_id);
}
if (!$cursor) {
return null;
}
$id_column = array(
'name' => 'r.id',
'type' => 'int',
'value' => $cursor->getID(),
);
$columns = array();
switch ($order) {
case self::ORDER_COMMITTED:
$commit = $cursor->getMostRecentCommit();
if (!$commit) {
return null;
}
$columns[] = array(
'name' => 's.epoch',
'type' => 'int',
'value' => $commit->getEpoch(),
);
$columns[] = $id_column;
break;
case self::ORDER_CALLSIGN:
$columns[] = array(
'name' => 'r.callsign',
'type' => 'string',
'value' => $cursor->getCallsign(),
'reverse' => true,
);
break;
case self::ORDER_NAME:
$columns[] = array(
'name' => 'r.name',
'type' => 'string',
'value' => $cursor->getName(),
'reverse' => true,
);
$columns[] = $id_column;
break;
default:
throw new Exception("Unknown order '{$order}'!");
}
return $this->buildPagingClauseFromMultipleColumns(
$conn_r,
$columns,
array(
// TODO: Clean up the column ordering stuff and then make this
// depend on getReversePaging().
'reversed' => (bool)($before_id),
));
}
private function buildJoinsClause(AphrontDatabaseConnection $conn_r) {
$joins = array();
$join_summary_table = $this->needCommitCounts ||
$this->needMostRecentCommits ||
($this->order == self::ORDER_COMMITTED);
if ($join_summary_table) {
$joins[] = qsprintf(
$conn_r,
'LEFT JOIN %T s ON r.id = s.repositoryID',
PhabricatorRepository::TABLE_SUMMARY);
}
if ($this->anyProjectPHIDs) {
$joins[] = qsprintf(
$conn_r,
'JOIN edge e ON e.src = r.phid');
}
return implode(' ', $joins);
}
private function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();
if ($this->ids) {
$where[] = qsprintf(
$conn_r,
'r.id IN (%Ld)',
$this->ids);
}
if ($this->phids) {
$where[] = qsprintf(
$conn_r,
'r.phid IN (%Ls)',
$this->phids);
}
if ($this->callsigns) {
$where[] = qsprintf(
$conn_r,
'r.callsign IN (%Ls)',
$this->callsigns);
}
if ($this->numericIdentifiers ||
$this->callsignIdentifiers ||
$this->phidIdentifiers) {
$identifier_clause = array();
if ($this->numericIdentifiers) {
$identifier_clause[] = qsprintf(
$conn_r,
'r.id IN (%Ld)',
$this->numericIdentifiers);
}
if ($this->callsignIdentifiers) {
$identifier_clause[] = qsprintf(
$conn_r,
'r.callsign IN (%Ls)',
$this->callsignIdentifiers);
}
if ($this->phidIdentifiers) {
$identifier_clause[] = qsprintf(
$conn_r,
'r.phid IN (%Ls)',
$this->phidIdentifiers);
}
$where = array('('.implode(' OR ', $identifier_clause).')');
}
if ($this->types) {
$where[] = qsprintf(
$conn_r,
'r.versionControlSystem IN (%Ls)',
$this->types);
}
if ($this->uuids) {
$where[] = qsprintf(
$conn_r,
'r.uuid IN (%Ls)',
$this->uuids);
}
if (strlen($this->nameContains)) {
$where[] = qsprintf(
$conn_r,
'name LIKE %~',
$this->nameContains);
}
if ($this->anyProjectPHIDs) {
$where[] = qsprintf(
$conn_r,
'e.dst IN (%Ls)',
$this->anyProjectPHIDs);
}
$where[] = $this->buildPagingClause($conn_r);
return $this->formatWhereClause($where);
}
public function getQueryApplicationClass() {
return 'PhabricatorDiffusionApplication';
}
private function getNormalizedPaths() {
$normalized_uris = array();
// Since we don't know which type of repository this URI is in the general
// case, just generate all the normalizations. We could refine this in some
// cases: if the query specifies VCS types, or the URI is a git-style URI
// or an `svn+ssh` URI, we could deduce how to normalize it. However, this
// would be more complicated and it's not clear if it matters in practice.
foreach ($this->remoteURIs as $uri) {
$normalized_uris[] = new PhabricatorRepositoryURINormalizer(
PhabricatorRepositoryURINormalizer::TYPE_GIT,
$uri);
$normalized_uris[] = new PhabricatorRepositoryURINormalizer(
PhabricatorRepositoryURINormalizer::TYPE_SVN,
$uri);
$normalized_uris[] = new PhabricatorRepositoryURINormalizer(
PhabricatorRepositoryURINormalizer::TYPE_MERCURIAL,
$uri);
}
return array_unique(mpull($normalized_uris, 'getNormalizedPath'));
}
}
diff --git a/src/applications/repository/query/PhabricatorRepositoryRefCursorQuery.php b/src/applications/repository/query/PhabricatorRepositoryRefCursorQuery.php
index 5dd6830e12..b75a8aa31e 100644
--- a/src/applications/repository/query/PhabricatorRepositoryRefCursorQuery.php
+++ b/src/applications/repository/query/PhabricatorRepositoryRefCursorQuery.php
@@ -1,100 +1,100 @@
<?php
final class PhabricatorRepositoryRefCursorQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
private $repositoryPHIDs;
private $refTypes;
private $refNames;
public function withRepositoryPHIDs(array $phids) {
$this->repositoryPHIDs = $phids;
return $this;
}
public function withRefTypes(array $types) {
$this->refTypes = $types;
return $this;
}
public function withRefNames(array $names) {
$this->refNames = $names;
return $this;
}
protected function loadPage() {
$table = new PhabricatorRepositoryRefCursor();
$conn_r = $table->establishConnection('r');
$data = queryfx_all(
$conn_r,
'SELECT * FROM %T r %Q %Q %Q',
$table->getTableName(),
$this->buildWhereClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
return $table->loadAllFromArray($data);
}
- public function willFilterPage(array $refs) {
+ protected function willFilterPage(array $refs) {
$repository_phids = mpull($refs, 'getRepositoryPHID');
$repositories = id(new PhabricatorRepositoryQuery())
->setViewer($this->getViewer())
->setParentQuery($this)
->withPHIDs($repository_phids)
->execute();
$repositories = mpull($repositories, null, 'getPHID');
foreach ($refs as $key => $ref) {
$repository = idx($repositories, $ref->getRepositoryPHID());
if (!$repository) {
unset($refs[$key]);
continue;
}
$ref->attachRepository($repository);
}
return $refs;
}
private function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();
if ($this->repositoryPHIDs !== null) {
$where[] = qsprintf(
$conn_r,
'repositoryPHID IN (%Ls)',
$this->repositoryPHIDs);
}
if ($this->refTypes !== null) {
$where[] = qsprintf(
$conn_r,
'refType IN (%Ls)',
$this->refTypes);
}
if ($this->refNames !== null) {
$name_hashes = array();
foreach ($this->refNames as $name) {
$name_hashes[] = PhabricatorHash::digestForIndex($name);
}
$where[] = qsprintf(
$conn_r,
'refNameHash IN (%Ls)',
$name_hashes);
}
$where[] = $this->buildPagingClause($conn_r);
return $this->formatWhereClause($where);
}
public function getQueryApplicationClass() {
return 'PhabricatorDiffusionApplication';
}
}
diff --git a/src/applications/slowvote/query/PhabricatorSlowvoteQuery.php b/src/applications/slowvote/query/PhabricatorSlowvoteQuery.php
index eb7849045b..f1ec5358f4 100644
--- a/src/applications/slowvote/query/PhabricatorSlowvoteQuery.php
+++ b/src/applications/slowvote/query/PhabricatorSlowvoteQuery.php
@@ -1,185 +1,185 @@
<?php
final class PhabricatorSlowvoteQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
private $ids;
private $phids;
private $authorPHIDs;
private $withVotesByViewer;
private $isClosed;
private $needOptions;
private $needChoices;
private $needViewerChoices;
public function withIDs($ids) {
$this->ids = $ids;
return $this;
}
public function withPHIDs($phids) {
$this->phids = $phids;
return $this;
}
public function withAuthorPHIDs($author_phids) {
$this->authorPHIDs = $author_phids;
return $this;
}
public function withVotesByViewer($with_vote) {
$this->withVotesByViewer = $with_vote;
return $this;
}
public function withIsClosed($with_closed) {
$this->isClosed = $with_closed;
return $this;
}
public function needOptions($need_options) {
$this->needOptions = $need_options;
return $this;
}
public function needChoices($need_choices) {
$this->needChoices = $need_choices;
return $this;
}
public function needViewerChoices($need_viewer_choices) {
$this->needViewerChoices = $need_viewer_choices;
return $this;
}
- public function loadPage() {
+ protected function loadPage() {
$table = new PhabricatorSlowvotePoll();
$conn_r = $table->establishConnection('r');
$data = queryfx_all(
$conn_r,
'SELECT p.* FROM %T p %Q %Q %Q %Q',
$table->getTableName(),
$this->buildJoinsClause($conn_r),
$this->buildWhereClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
return $table->loadAllFromArray($data);
}
- public function willFilterPage(array $polls) {
+ protected function willFilterPage(array $polls) {
assert_instances_of($polls, 'PhabricatorSlowvotePoll');
$ids = mpull($polls, 'getID');
$viewer = $this->getViewer();
if ($this->needOptions) {
$options = id(new PhabricatorSlowvoteOption())->loadAllWhere(
'pollID IN (%Ld)',
$ids);
$options = mgroup($options, 'getPollID');
foreach ($polls as $poll) {
$poll->attachOptions(idx($options, $poll->getID(), array()));
}
}
if ($this->needChoices) {
$choices = id(new PhabricatorSlowvoteChoice())->loadAllWhere(
'pollID IN (%Ld)',
$ids);
$choices = mgroup($choices, 'getPollID');
foreach ($polls as $poll) {
$poll->attachChoices(idx($choices, $poll->getID(), array()));
}
// If we need the viewer's choices, we can just fill them from the data
// we already loaded.
if ($this->needViewerChoices) {
foreach ($polls as $poll) {
$poll->attachViewerChoices(
$viewer,
idx(
mgroup($poll->getChoices(), 'getAuthorPHID'),
$viewer->getPHID(),
array()));
}
}
} else if ($this->needViewerChoices) {
$choices = id(new PhabricatorSlowvoteChoice())->loadAllWhere(
'pollID IN (%Ld) AND authorPHID = %s',
$ids,
$viewer->getPHID());
$choices = mgroup($choices, 'getPollID');
foreach ($polls as $poll) {
$poll->attachViewerChoices(
$viewer,
idx($choices, $poll->getID(), array()));
}
}
return $polls;
}
private function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();
if ($this->ids) {
$where[] = qsprintf(
$conn_r,
'p.id IN (%Ld)',
$this->ids);
}
if ($this->phids) {
$where[] = qsprintf(
$conn_r,
'p.phid IN (%Ls)',
$this->phids);
}
if ($this->authorPHIDs) {
$where[] = qsprintf(
$conn_r,
'p.authorPHID IN (%Ls)',
$this->authorPHIDs);
}
if ($this->isClosed !== null) {
$where[] = qsprintf(
$conn_r,
'p.isClosed = %d',
(int)$this->isClosed);
}
$where[] = $this->buildPagingClause($conn_r);
return $this->formatWhereClause($where);
}
private function buildJoinsClause(AphrontDatabaseConnection $conn_r) {
$joins = array();
if ($this->withVotesByViewer) {
$joins[] = qsprintf(
$conn_r,
'JOIN %T vv ON vv.pollID = p.id AND vv.authorPHID = %s',
id(new PhabricatorSlowvoteChoice())->getTableName(),
$this->getViewer()->getPHID());
}
return implode(' ', $joins);
}
protected function getPagingColumn() {
return 'p.id';
}
public function getQueryApplicationClass() {
return 'PhabricatorSlowvoteApplication';
}
}
diff --git a/src/applications/tokens/query/PhabricatorTokenGivenQuery.php b/src/applications/tokens/query/PhabricatorTokenGivenQuery.php
index 35ca0b8407..896b4532c9 100644
--- a/src/applications/tokens/query/PhabricatorTokenGivenQuery.php
+++ b/src/applications/tokens/query/PhabricatorTokenGivenQuery.php
@@ -1,96 +1,96 @@
<?php
final class PhabricatorTokenGivenQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
private $authorPHIDs;
private $objectPHIDs;
private $tokenPHIDs;
public function withTokenPHIDs(array $token_phids) {
$this->tokenPHIDs = $token_phids;
return $this;
}
public function withObjectPHIDs(array $object_phids) {
$this->objectPHIDs = $object_phids;
return $this;
}
public function withAuthorPHIDs(array $author_phids) {
$this->authorPHIDs = $author_phids;
return $this;
}
protected function loadPage() {
$table = new PhabricatorTokenGiven();
$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));
return $table->loadAllFromArray($rows);
}
private function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();
if ($this->authorPHIDs) {
$where[] = qsprintf(
$conn_r,
'authorPHID IN (%Ls)',
$this->authorPHIDs);
}
if ($this->objectPHIDs) {
$where[] = qsprintf(
$conn_r,
'objectPHID IN (%Ls)',
$this->objectPHIDs);
}
if ($this->tokenPHIDs) {
$where[] = qsprintf(
$conn_r,
'tokenPHID IN (%Ls)',
$this->tokenPHIDs);
}
$where[] = $this->buildPagingClause($conn_r);
return $this->formatWhereClause($where);
}
- public function willFilterPage(array $results) {
+ protected function willFilterPage(array $results) {
$object_phids = array_filter(mpull($results, 'getObjectPHID'));
if (!$object_phids) {
return array();
}
$objects = id(new PhabricatorObjectQuery())
->setViewer($this->getViewer())
->withPHIDs($object_phids)
->execute();
foreach ($results as $key => $result) {
$phid = $result->getObjectPHID();
if (empty($objects[$phid])) {
unset($results[$key]);
} else {
$result->attachObject($objects[$phid]);
}
}
return $results;
}
public function getQueryApplicationClass() {
return 'PhabricatorTokensApplication';
}
}
diff --git a/src/applications/tokens/query/PhabricatorTokenReceiverQuery.php b/src/applications/tokens/query/PhabricatorTokenReceiverQuery.php
index eb670a0fd6..2eb8158418 100644
--- a/src/applications/tokens/query/PhabricatorTokenReceiverQuery.php
+++ b/src/applications/tokens/query/PhabricatorTokenReceiverQuery.php
@@ -1,41 +1,41 @@
<?php
final class PhabricatorTokenReceiverQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
private $tokenCounts;
protected function loadPage() {
$table = new PhabricatorTokenCount();
$conn_r = $table->establishConnection('r');
$rows = queryfx_all(
$conn_r,
'SELECT objectPHID, tokenCount FROM %T ORDER BY tokenCount DESC',
$table->getTableName());
$this->tokenCounts = ipull($rows, 'tokenCount', 'objectPHID');
return ipull($rows, 'objectPHID');
}
- public function willFilterPage(array $phids) {
+ protected function willFilterPage(array $phids) {
$objects = id(new PhabricatorObjectQuery())
->setViewer($this->getViewer())
->withPHIDs($phids)
->execute();
// Reorder the objects in the input order.
$objects = array_select_keys($objects, $phids);
return $objects;
}
public function getTokenCounts() {
return $this->tokenCounts;
}
public function getQueryApplicationClass() {
return 'PhabricatorTokensApplication';
}
}

File Metadata

Mime Type
text/x-diff
Expires
Tue, Feb 24, 7:16 PM (18 h, 57 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
851016
Default Alt Text
(267 KB)

Event Timeline