1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-11-25 16:22:43 +01:00

Merge branch 'master' into redesign-2015

This commit is contained in:
epriestley 2015-06-10 07:44:58 -07:00
commit 57b898af9a
452 changed files with 10749 additions and 5241 deletions

View file

@ -1,7 +1,6 @@
<?php
function phabricator_read_config_file($original_config) {
$root = dirname(dirname(__FILE__));
// Accept either "myconfig" (preferred) or "myconfig.conf.php".
@ -9,7 +8,6 @@ function phabricator_read_config_file($original_config) {
$full_config_path = $root.'/conf/'.$config.'.conf.php';
if (!Filesystem::pathExists($full_config_path)) {
// These are very old configuration files which we used to ship with
// by default. File based configuration was de-emphasized once web-based
// configuration was built. The actual files were removed to reduce
@ -37,12 +35,14 @@ function phabricator_read_config_file($original_config) {
$file = trim($file, './');
$files[$key] = preg_replace('/\.conf\.php$/', '', $file);
}
$files = " ".implode("\n ", $files);
$files = ' '.implode("\n ", $files);
throw new Exception(
"CONFIGURATION ERROR\n".
"Config file '{$original_config}' does not exist. Valid config files ".
"are:\n\n".$files);
pht(
"CONFIGURATION ERROR\n".
"Config file '%s' does not exist. Valid config files are:\n\n%s",
$original_config,
$files));
}
// Make sure config file errors are reported.
@ -58,7 +58,11 @@ function phabricator_read_config_file($original_config) {
ini_set('display_errors', $old_display_errors);
if ($conf === false) {
throw new Exception("Failed to read config file '{$config}': {$errors}");
throw new Exception(
pht(
"Failed to read config file '%s': %s",
$config,
$errors));
}
return $conf;

View file

@ -1,26 +1,29 @@
<?php
$projects = id(new PhabricatorRepositoryArcanistProjectQuery())
->setViewer(PhabricatorUser::getOmnipotentUser())
->needRepositories(true)
->execute();
$table = new PhabricatorRepositorySymbol();
$conn_w = $table->establishConnection('w');
$projects = queryfx_all(
$conn_w,
'SELECT * FROM %T',
'repository_arcanistproject');
foreach ($projects as $project) {
$repo = $project->getRepository();
$repo = id(new PhabricatorRepositoryQuery())
->setViewer(PhabricatorUser::getOmnipotentUser())
->withIDs(array($project['repositoryID']))
->executeOne();
if (!$repo) {
continue;
}
echo pht("Migrating symbols for '%s' project...\n", $project->getName());
echo pht("Migrating symbols for '%s' project...\n", $project['name']);
queryfx(
$conn_w,
'UPDATE %T SET repositoryPHID = %s WHERE arcanistProjectID = %d',
$table->getTableName(),
$repo->getPHID(),
$project->getID());
$project['id']);
}

View file

@ -11,6 +11,10 @@ $raw_projects_data = queryfx_all($conn_r, 'SELECT * FROM %T', $projects_table);
$raw_projects_data = ipull($raw_projects_data, null, 'id');
$repository_ids = ipull($raw_projects_data, 'repositoryID');
if (!$repository_ids) {
return;
}
$repositories = id(new PhabricatorRepositoryQuery())
->setViewer(PhabricatorUser::getOmnipotentUser())
->withIDs($repository_ids)

View file

@ -0,0 +1,17 @@
ALTER TABLE {$NAMESPACE}_calendar.calendar_event
ADD isRecurring BOOL NOT NULL;
ALTER TABLE {$NAMESPACE}_calendar.calendar_event
ADD recurrenceFrequency LONGTEXT COLLATE {$COLLATE_TEXT} NOT NULL;
ALTER TABLE {$NAMESPACE}_calendar.calendar_event
ADD recurrenceEndDate INT UNSIGNED;
ALTER TABLE {$NAMESPACE}_calendar.calendar_event
ADD instanceOfEventPHID varbinary(64);
ALTER TABLE {$NAMESPACE}_calendar.calendar_event
ADD sequenceIndex INT UNSIGNED;
UPDATE {$NAMESPACE}_calendar.calendar_event
SET recurrenceFrequency = '[]' WHERE recurrenceFrequency = '';

View file

@ -0,0 +1,12 @@
CREATE TABLE {$NAMESPACE}_spaces.spaces_namespace (
id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
phid VARBINARY(64) NOT NULL,
namespaceName VARCHAR(255) NOT NULL COLLATE {$COLLATE_TEXT},
viewPolicy VARBINARY(64) NOT NULL,
editPolicy VARBINARY(64) NOT NULL,
isDefaultNamespace BOOL,
dateCreated INT UNSIGNED NOT NULL,
dateModified INT UNSIGNED NOT NULL,
UNIQUE KEY `key_phid` (phid),
UNIQUE KEY `key_default` (isDefaultNamespace)
) ENGINE=InnoDB, COLLATE {$COLLATE_TEXT};

View file

@ -0,0 +1,19 @@
CREATE TABLE {$NAMESPACE}_spaces.spaces_namespacetransaction (
id INT UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
phid VARBINARY(64) NOT NULL,
authorPHID VARBINARY(64) NOT NULL,
objectPHID VARBINARY(64) NOT NULL,
viewPolicy VARBINARY(64) NOT NULL,
editPolicy VARBINARY(64) NOT NULL,
commentPHID VARBINARY(64),
commentVersion INT UNSIGNED NOT NULL,
transactionType VARCHAR(32) NOT NULL COLLATE {$COLLATE_TEXT},
oldValue LONGTEXT NOT NULL COLLATE {$COLLATE_TEXT},
newValue LONGTEXT NOT NULL COLLATE {$COLLATE_TEXT},
contentSource LONGTEXT NOT NULL COLLATE {$COLLATE_TEXT},
metadata LONGTEXT NOT NULL COLLATE {$COLLATE_TEXT},
dateCreated INT UNSIGNED NOT NULL,
dateModified INT UNSIGNED NOT NULL,
UNIQUE KEY `key_phid` (phid),
KEY `key_object` (objectPHID)
) ENGINE=InnoDB, COLLATE {$COLLATE_TEXT};

View file

@ -0,0 +1,2 @@
ALTER TABLE {$NAMESPACE}_user.user
ADD isMailingList BOOL NOT NULL;

View file

@ -0,0 +1,145 @@
<?php
$conn_w = id(new PhabricatorMetaMTAMail())->establishConnection('w');
$lists = new LiskRawMigrationIterator($conn_w, 'metamta_mailinglist');
echo pht('Migrating mailing lists...')."\n";
foreach ($lists as $list) {
$name = $list['name'];
$email = $list['email'];
$uri = $list['uri'];
$old_phid = $list['phid'];
$username = preg_replace('/[^a-zA-Z0-9_-]+/', '-', $name);
$username = preg_replace('/-{2,}/', '-', $username);
$username = trim($username, '-');
if (!strlen($username)) {
$username = 'mailinglist';
}
$username .= '-list';
$username_okay = false;
for ($suffix = 1; $suffix <= 9; $suffix++) {
if ($suffix == 1) {
$effective_username = $username;
} else {
$effective_username = $username.$suffix;
}
$collision = id(new PhabricatorPeopleQuery())
->setViewer(PhabricatorUser::getOmnipotentUser())
->withUsernames(array($effective_username))
->executeOne();
if (!$collision) {
$username_okay = true;
break;
}
}
if (!$username_okay) {
echo pht(
'Failed to migrate mailing list "%s": unable to generate a unique '.
'username for it.')."\n";
continue;
}
$username = $effective_username;
if (!PhabricatorUser::validateUsername($username)) {
echo pht(
'Failed to migrate mailing list "%s": unable to generate a valid '.
'username for it.',
$name)."\n";
continue;
}
$address = id(new PhabricatorUserEmail())->loadOneWhere(
'address = %s',
$email);
if ($address) {
echo pht(
'Failed to migrate mailing list "%s": an existing user already '.
'has the email address "%s".',
$name,
$email)."\n";
continue;
}
$user = id(new PhabricatorUser())
->setUsername($username)
->setRealName(pht('Mailing List "%s"', $name))
->setIsApproved(1)
->setIsMailingList(1);
$email_object = id(new PhabricatorUserEmail())
->setAddress($email)
->setIsVerified(1);
try {
id(new PhabricatorUserEditor())
->setActor($user)
->createNewUser($user, $email_object);
} catch (Exception $ex) {
echo pht(
'Failed to migrate mailing list "%s": %s.',
$name,
$ex->getMessage())."\n";
continue;
}
$new_phid = $user->getPHID();
// NOTE: After the PHID type is removed we can't use any Edge code to
// modify edges.
$edge_type = PhabricatorSubscribedToObjectEdgeType::EDGECONST;
$edge_inverse = PhabricatorObjectHasSubscriberEdgeType::EDGECONST;
$map = PhabricatorPHIDType::getAllTypes();
foreach ($map as $type => $spec) {
try {
$object = $spec->newObject();
if (!$object) {
continue;
}
$object_conn_w = $object->establishConnection('w');
queryfx(
$object_conn_w,
'UPDATE %T SET dst = %s WHERE dst = %s AND type = %s',
PhabricatorEdgeConfig::TABLE_NAME_EDGE,
$new_phid,
$old_phid,
$edge_inverse);
} catch (Exception $ex) {
// Just ignore these; they're mostly tables not existing.
continue;
}
}
try {
$dst_phids = queryfx_all(
$conn_w,
'SELECT dst FROM %T WHERE src = %s AND type = %s',
PhabricatorEdgeConfig::TABLE_NAME_EDGE,
$old_phid,
$edge_type);
if ($dst_phids) {
$editor = new PhabricatorEdgeEditor();
foreach ($dst_phids as $dst_phid) {
$editor->addEdge($new_phid, $edge_type, $dst_phid['dst']);
}
$editor->save();
}
} catch (Exception $ex) {
echo pht(
'Unable to migrate some inverse edges for mailing list "%s": %s.',
$name,
$ex->getMessage())."\n";
continue;
}
echo pht(
'Migrated mailing list "%s" to mailing list user "%s".',
$name,
$user->getUsername())."\n";
}

View file

@ -0,0 +1,2 @@
ALTER TABLE {$NAMESPACE}_pastebin.pastebin_paste
ADD spacePHID VARBINARY(64);

View file

@ -0,0 +1,152 @@
<?php
$conn_r = id(new PhabricatorMetaMTAMail())->establishConnection('r');
$rows = queryfx_all(
$conn_r,
'SELECT phid, email FROM %T',
'metamta_mailinglist');
if (!$rows) {
echo pht('No mailing lists to migrate.')."\n";
return;
}
$list_map = array();
foreach ($rows as $row) {
$list_map[phutil_utf8_strtolower($row['email'])] = $row['phid'];
}
$emails = id(new PhabricatorUserEmail())->loadAllWhere(
'address IN (%Ls)',
array_keys($list_map));
if (!$emails) {
echo pht('No mailing lists match addresses.')."\n";
return;
}
// Create a map from old mailing list PHIDs to new user PHIDs.
$map = array();
foreach ($emails as $email) {
$user_phid = $email->getUserPHID();
if (!$user_phid) {
continue;
}
$address = $email->getAddress();
$address = phutil_utf8_strtolower($address);
if (isset($list_map[$address])) {
$map[$list_map[$address]] = $user_phid;
}
}
if (!$map) {
echo pht('No mailing lists match users.')."\n";
return;
}
echo pht('Migrating Herald conditions which use mailing lists..')."\n";
$table = new HeraldCondition();
$conn_w = $table->establishConnection('w');
foreach (new LiskMigrationIterator($table) as $condition) {
$name = $condition->getFieldName();
if ($name == 'cc') {
// Okay, we can migrate these.
} else {
// This is not a condition type which has mailing lists in its value, so
// don't try to migrate it.
continue;
}
$value = $condition->getValue();
if (!is_array($value)) {
// Only migrate PHID lists.
continue;
}
foreach ($value as $v) {
if (!is_string($v)) {
// Only migrate PHID lists where all members are PHIDs.
continue 2;
}
}
$new = array();
$any_change = false;
foreach ($value as $v) {
if (isset($map[$v])) {
$new[] = $map[$v];
$any_change = true;
} else {
$new[] = $v;
}
}
if (!$any_change) {
continue;
}
$id = $condition->getID();
queryfx(
$conn_w,
'UPDATE %T SET value = %s WHERE id = %d',
$table->getTableName(),
json_encode($new),
$id);
echo pht('Updated mailing lists in Herald condition %d.', $id)."\n";
}
$table = new HeraldAction();
$conn_w = $table->establishConnection('w');
foreach (new LiskMigrationIterator($table) as $action) {
$name = $action->getAction();
if ($name == 'addcc' || $name == 'remcc') {
// Okay, we can migrate these.
} else {
// This is not an action type which has mailing lists in its targets, so
// don't try to migrate it.
continue;
}
$value = $action->getTarget();
if (!is_array($value)) {
// Only migrate PHID lists.
continue;
}
foreach ($value as $v) {
if (!is_string($v)) {
// Only migrate PHID lists where all members are PHIDs.
continue 2;
}
}
$new = array();
$any_change = false;
foreach ($value as $v) {
if (isset($map[$v])) {
$new[] = $map[$v];
$any_change = true;
} else {
$new[] = $v;
}
}
if (!$any_change) {
continue;
}
$id = $action->getID();
queryfx(
$conn_w,
'UPDATE %T SET target = %s WHERE id = %d',
$table->getTableName(),
json_encode($new),
$id);
echo pht('Updated mailing lists in Herald action %d.', $id)."\n";
}

View file

@ -0,0 +1,4 @@
/* This cleans up some errant transactions, see T8483. */
DELETE FROM {$NAMESPACE}_differential.differential_transaction
WHERE transactionType = 'core:inlinestate' AND newValue = 'null';

View file

@ -1,35 +1,3 @@
<?php
$table = new DifferentialRevision();
$table->openTransaction();
$table->beginReadLocking();
$conn_w = $table->establishConnection('w');
echo pht('Migrating revisions')."\n";
do {
$revisions = $table->loadAllWhere('branchName IS NULL LIMIT 1000');
foreach ($revisions as $revision) {
echo '.';
$diff = $revision->loadActiveDiff();
if (!$diff) {
continue;
}
$branch_name = $diff->getBranch();
$arc_project_phid = $diff->getArcanistProjectPHID();
queryfx(
$conn_w,
'UPDATE %T SET branchName = %s, arcanistProjectPHID = %s WHERE id = %d',
$table->getTableName(),
$branch_name,
$arc_project_phid,
$revision->getID());
}
} while (count($revisions) == 1000);
$table->endReadLocking();
$table->saveTransaction();
echo "\n".pht('Done.')."\n";
// This migration has been dropped, see T7604 for details.

View file

@ -5,4 +5,4 @@
// already migrated, so this was cleaned up when ReleephRequestEvent was
// removed.
echo "(This migration is obsolete.)\n";
echo pht('(This migration is obsolete.)')."\n";

View file

@ -182,11 +182,11 @@ try {
'P' => $user->getPHID(),
));
if (!$user->isUserActivated()) {
if (!$user->canEstablishSSHSessions()) {
throw new Exception(
pht(
'Your account ("%s") is not activated. Visit the web interface '.
'for more information.',
'Your account ("%s") does not have permission to establish SSH '.
'sessions. Visit the web interface for more information.',
$user->getUsername()));
}

View file

@ -125,7 +125,7 @@ if (strlen($password)) {
$is_system_agent = $user->getIsSystemAgent();
$set_system_agent = phutil_console_confirm(
pht('Is this user a bot/script?'),
pht('Is this user a bot?'),
$default_no = !$is_system_agent);
$verify_email = null;
@ -165,7 +165,7 @@ printf($tpl, pht('Password'), null,
printf(
$tpl,
pht('Bot/Script'),
pht('Bot'),
$original->getIsSystemAgent() ? 'Y' : 'N',
$set_system_agent ? 'Y' : 'N');

View file

@ -175,8 +175,6 @@ phutil_register_library_map(array(
'AuditConduitAPIMethod' => 'applications/audit/conduit/AuditConduitAPIMethod.php',
'AuditQueryConduitAPIMethod' => 'applications/audit/conduit/AuditQueryConduitAPIMethod.php',
'AuthManageProvidersCapability' => 'applications/auth/capability/AuthManageProvidersCapability.php',
'CalendarColors' => 'applications/calendar/constants/CalendarColors.php',
'CalendarConstants' => 'applications/calendar/constants/CalendarConstants.php',
'CalendarTimeUtil' => 'applications/calendar/util/CalendarTimeUtil.php',
'CalendarTimeUtilTestCase' => 'applications/calendar/__tests__/CalendarTimeUtilTestCase.php',
'CelerityAPI' => 'applications/celerity/CelerityAPI.php',
@ -265,7 +263,6 @@ phutil_register_library_map(array(
'ConpherenceTransactionComment' => 'applications/conpherence/storage/ConpherenceTransactionComment.php',
'ConpherenceTransactionQuery' => 'applications/conpherence/query/ConpherenceTransactionQuery.php',
'ConpherenceTransactionRenderer' => 'applications/conpherence/ConpherenceTransactionRenderer.php',
'ConpherenceTransactionType' => 'applications/conpherence/constants/ConpherenceTransactionType.php',
'ConpherenceTransactionView' => 'applications/conpherence/view/ConpherenceTransactionView.php',
'ConpherenceUpdateActions' => 'applications/conpherence/constants/ConpherenceUpdateActions.php',
'ConpherenceUpdateController' => 'applications/conpherence/controller/ConpherenceUpdateController.php',
@ -506,6 +503,8 @@ phutil_register_library_map(array(
'DiffusionEmptyResultView' => 'applications/diffusion/view/DiffusionEmptyResultView.php',
'DiffusionExistsQueryConduitAPIMethod' => 'applications/diffusion/conduit/DiffusionExistsQueryConduitAPIMethod.php',
'DiffusionExternalController' => 'applications/diffusion/controller/DiffusionExternalController.php',
'DiffusionExternalSymbolQuery' => 'applications/diffusion/symbol/DiffusionExternalSymbolQuery.php',
'DiffusionExternalSymbolsSource' => 'applications/diffusion/symbol/DiffusionExternalSymbolsSource.php',
'DiffusionFileContent' => 'applications/diffusion/data/DiffusionFileContent.php',
'DiffusionFileContentQuery' => 'applications/diffusion/query/filecontent/DiffusionFileContentQuery.php',
'DiffusionFileContentQueryConduitAPIMethod' => 'applications/diffusion/conduit/DiffusionFileContentQueryConduitAPIMethod.php',
@ -564,11 +563,13 @@ phutil_register_library_map(array(
'DiffusionPathQueryTestCase' => 'applications/diffusion/query/pathid/__tests__/DiffusionPathQueryTestCase.php',
'DiffusionPathTreeController' => 'applications/diffusion/controller/DiffusionPathTreeController.php',
'DiffusionPathValidateController' => 'applications/diffusion/controller/DiffusionPathValidateController.php',
'DiffusionPhpExternalSymbolsSource' => 'applications/diffusion/symbol/DiffusionPhpExternalSymbolsSource.php',
'DiffusionPushCapability' => 'applications/diffusion/capability/DiffusionPushCapability.php',
'DiffusionPushEventViewController' => 'applications/diffusion/controller/DiffusionPushEventViewController.php',
'DiffusionPushLogController' => 'applications/diffusion/controller/DiffusionPushLogController.php',
'DiffusionPushLogListController' => 'applications/diffusion/controller/DiffusionPushLogListController.php',
'DiffusionPushLogListView' => 'applications/diffusion/view/DiffusionPushLogListView.php',
'DiffusionPythonExternalSymbolsSource' => 'applications/diffusion/symbol/DiffusionPythonExternalSymbolsSource.php',
'DiffusionQuery' => 'applications/diffusion/query/DiffusionQuery.php',
'DiffusionQueryCommitsConduitAPIMethod' => 'applications/diffusion/conduit/DiffusionQueryCommitsConduitAPIMethod.php',
'DiffusionQueryConduitAPIMethod' => 'applications/diffusion/conduit/DiffusionQueryConduitAPIMethod.php',
@ -639,12 +640,14 @@ phutil_register_library_map(array(
'DivinerAtomQuery' => 'applications/diviner/query/DivinerAtomQuery.php',
'DivinerAtomRef' => 'applications/diviner/atom/DivinerAtomRef.php',
'DivinerAtomSearchEngine' => 'applications/diviner/query/DivinerAtomSearchEngine.php',
'DivinerAtomSearchIndexer' => 'applications/diviner/search/DivinerAtomSearchIndexer.php',
'DivinerAtomizeWorkflow' => 'applications/diviner/workflow/DivinerAtomizeWorkflow.php',
'DivinerAtomizer' => 'applications/diviner/atomizer/DivinerAtomizer.php',
'DivinerBookController' => 'applications/diviner/controller/DivinerBookController.php',
'DivinerBookItemView' => 'applications/diviner/view/DivinerBookItemView.php',
'DivinerBookPHIDType' => 'applications/diviner/phid/DivinerBookPHIDType.php',
'DivinerBookQuery' => 'applications/diviner/query/DivinerBookQuery.php',
'DivinerBookSearchIndexer' => 'applications/diviner/search/DivinerBookSearchIndexer.php',
'DivinerController' => 'applications/diviner/controller/DivinerController.php',
'DivinerDAO' => 'applications/diviner/storage/DivinerDAO.php',
'DivinerDefaultRenderer' => 'applications/diviner/renderer/DivinerDefaultRenderer.php',
@ -668,6 +671,7 @@ phutil_register_library_map(array(
'DivinerSymbolRemarkupRule' => 'applications/diviner/markup/DivinerSymbolRemarkupRule.php',
'DivinerWorkflow' => 'applications/diviner/workflow/DivinerWorkflow.php',
'DoorkeeperAsanaFeedWorker' => 'applications/doorkeeper/worker/DoorkeeperAsanaFeedWorker.php',
'DoorkeeperAsanaRemarkupRule' => 'applications/doorkeeper/remarkup/DoorkeeperAsanaRemarkupRule.php',
'DoorkeeperBridge' => 'applications/doorkeeper/bridge/DoorkeeperBridge.php',
'DoorkeeperBridgeAsana' => 'applications/doorkeeper/bridge/DoorkeeperBridgeAsana.php',
'DoorkeeperBridgeJIRA' => 'applications/doorkeeper/bridge/DoorkeeperBridgeJIRA.php',
@ -679,11 +683,10 @@ phutil_register_library_map(array(
'DoorkeeperFeedWorker' => 'applications/doorkeeper/worker/DoorkeeperFeedWorker.php',
'DoorkeeperImportEngine' => 'applications/doorkeeper/engine/DoorkeeperImportEngine.php',
'DoorkeeperJIRAFeedWorker' => 'applications/doorkeeper/worker/DoorkeeperJIRAFeedWorker.php',
'DoorkeeperJIRARemarkupRule' => 'applications/doorkeeper/remarkup/DoorkeeperJIRARemarkupRule.php',
'DoorkeeperMissingLinkException' => 'applications/doorkeeper/exception/DoorkeeperMissingLinkException.php',
'DoorkeeperObjectRef' => 'applications/doorkeeper/engine/DoorkeeperObjectRef.php',
'DoorkeeperRemarkupRule' => 'applications/doorkeeper/remarkup/DoorkeeperRemarkupRule.php',
'DoorkeeperRemarkupRuleAsana' => 'applications/doorkeeper/remarkup/DoorkeeperRemarkupRuleAsana.php',
'DoorkeeperRemarkupRuleJIRA' => 'applications/doorkeeper/remarkup/DoorkeeperRemarkupRuleJIRA.php',
'DoorkeeperSchemaSpec' => 'applications/doorkeeper/storage/DoorkeeperSchemaSpec.php',
'DoorkeeperTagView' => 'applications/doorkeeper/view/DoorkeeperTagView.php',
'DoorkeeperTagsController' => 'applications/doorkeeper/controller/DoorkeeperTagsController.php',
@ -951,7 +954,6 @@ phutil_register_library_map(array(
'JavelinUIExample' => 'applications/uiexample/examples/JavelinUIExample.php',
'JavelinViewExampleServerView' => 'applications/uiexample/examples/JavelinViewExampleServerView.php',
'JavelinViewUIExample' => 'applications/uiexample/examples/JavelinViewUIExample.php',
'LegalpadConstants' => 'applications/legalpad/constants/LegalpadConstants.php',
'LegalpadController' => 'applications/legalpad/controller/LegalpadController.php',
'LegalpadCreateDocumentsCapability' => 'applications/legalpad/capability/LegalpadCreateDocumentsCapability.php',
'LegalpadDAO' => 'applications/legalpad/storage/LegalpadDAO.php',
@ -985,7 +987,6 @@ phutil_register_library_map(array(
'LegalpadTransaction' => 'applications/legalpad/storage/LegalpadTransaction.php',
'LegalpadTransactionComment' => 'applications/legalpad/storage/LegalpadTransactionComment.php',
'LegalpadTransactionQuery' => 'applications/legalpad/query/LegalpadTransactionQuery.php',
'LegalpadTransactionType' => 'applications/legalpad/constants/LegalpadTransactionType.php',
'LegalpadTransactionView' => 'applications/legalpad/view/LegalpadTransactionView.php',
'LiskChunkTestCase' => 'infrastructure/storage/lisk/__tests__/LiskChunkTestCase.php',
'LiskDAO' => 'infrastructure/storage/lisk/LiskDAO.php',
@ -1083,7 +1084,6 @@ phutil_register_library_map(array(
'MetaMTAEmailTransactionCommand' => 'applications/metamta/command/MetaMTAEmailTransactionCommand.php',
'MetaMTAMailReceivedGarbageCollector' => 'applications/metamta/garbagecollector/MetaMTAMailReceivedGarbageCollector.php',
'MetaMTAMailSentGarbageCollector' => 'applications/metamta/garbagecollector/MetaMTAMailSentGarbageCollector.php',
'MetaMTANotificationType' => 'applications/metamta/constants/MetaMTANotificationType.php',
'MetaMTAReceivedMailStatus' => 'applications/metamta/constants/MetaMTAReceivedMailStatus.php',
'MultimeterContext' => 'applications/multimeter/storage/MultimeterContext.php',
'MultimeterControl' => 'applications/multimeter/data/MultimeterControl.php',
@ -1115,8 +1115,10 @@ phutil_register_library_map(array(
'NuanceQueueEditController' => 'applications/nuance/controller/NuanceQueueEditController.php',
'NuanceQueueEditor' => 'applications/nuance/editor/NuanceQueueEditor.php',
'NuanceQueueItem' => 'applications/nuance/storage/NuanceQueueItem.php',
'NuanceQueueListController' => 'applications/nuance/controller/NuanceQueueListController.php',
'NuanceQueuePHIDType' => 'applications/nuance/phid/NuanceQueuePHIDType.php',
'NuanceQueueQuery' => 'applications/nuance/query/NuanceQueueQuery.php',
'NuanceQueueSearchEngine' => 'applications/nuance/query/NuanceQueueSearchEngine.php',
'NuanceQueueTransaction' => 'applications/nuance/storage/NuanceQueueTransaction.php',
'NuanceQueueTransactionComment' => 'applications/nuance/storage/NuanceQueueTransactionComment.php',
'NuanceQueueTransactionQuery' => 'applications/nuance/query/NuanceQueueTransactionQuery.php',
@ -1133,14 +1135,18 @@ phutil_register_library_map(array(
'NuanceRequestorViewController' => 'applications/nuance/controller/NuanceRequestorViewController.php',
'NuanceSchemaSpec' => 'applications/nuance/storage/NuanceSchemaSpec.php',
'NuanceSource' => 'applications/nuance/storage/NuanceSource.php',
'NuanceSourceActionController' => 'applications/nuance/controller/NuanceSourceActionController.php',
'NuanceSourceCreateController' => 'applications/nuance/controller/NuanceSourceCreateController.php',
'NuanceSourceDefaultEditCapability' => 'applications/nuance/capability/NuanceSourceDefaultEditCapability.php',
'NuanceSourceDefaultViewCapability' => 'applications/nuance/capability/NuanceSourceDefaultViewCapability.php',
'NuanceSourceDefinition' => 'applications/nuance/source/NuanceSourceDefinition.php',
'NuanceSourceEditController' => 'applications/nuance/controller/NuanceSourceEditController.php',
'NuanceSourceEditor' => 'applications/nuance/editor/NuanceSourceEditor.php',
'NuanceSourceListController' => 'applications/nuance/controller/NuanceSourceListController.php',
'NuanceSourceManageCapability' => 'applications/nuance/capability/NuanceSourceManageCapability.php',
'NuanceSourcePHIDType' => 'applications/nuance/phid/NuanceSourcePHIDType.php',
'NuanceSourceQuery' => 'applications/nuance/query/NuanceSourceQuery.php',
'NuanceSourceSearchEngine' => 'applications/nuance/query/NuanceSourceSearchEngine.php',
'NuanceSourceTransaction' => 'applications/nuance/storage/NuanceSourceTransaction.php',
'NuanceSourceTransactionComment' => 'applications/nuance/storage/NuanceSourceTransactionComment.php',
'NuanceSourceTransactionQuery' => 'applications/nuance/query/NuanceSourceTransactionQuery.php',
@ -1216,6 +1222,7 @@ phutil_register_library_map(array(
'PHUIPropertyListExample' => 'applications/uiexample/examples/PHUIPropertyListExample.php',
'PHUIPropertyListView' => 'view/phui/PHUIPropertyListView.php',
'PHUIRemarkupPreviewPanel' => 'view/phui/PHUIRemarkupPreviewPanel.php',
'PHUISpacesNamespaceContextView' => 'applications/spaces/view/PHUISpacesNamespaceContextView.php',
'PHUIStatusItemView' => 'view/phui/PHUIStatusItemView.php',
'PHUIStatusListView' => 'view/phui/PHUIStatusListView.php',
'PHUITagExample' => 'applications/uiexample/examples/PHUITagExample.php',
@ -1330,6 +1337,7 @@ phutil_register_library_map(array(
'PhabricatorApplicationTransactionInterface' => 'applications/transactions/interface/PhabricatorApplicationTransactionInterface.php',
'PhabricatorApplicationTransactionNoEffectException' => 'applications/transactions/exception/PhabricatorApplicationTransactionNoEffectException.php',
'PhabricatorApplicationTransactionNoEffectResponse' => 'applications/transactions/response/PhabricatorApplicationTransactionNoEffectResponse.php',
'PhabricatorApplicationTransactionPublishWorker' => 'applications/transactions/worker/PhabricatorApplicationTransactionPublishWorker.php',
'PhabricatorApplicationTransactionQuery' => 'applications/transactions/query/PhabricatorApplicationTransactionQuery.php',
'PhabricatorApplicationTransactionReplyHandler' => 'applications/transactions/replyhandler/PhabricatorApplicationTransactionReplyHandler.php',
'PhabricatorApplicationTransactionResponse' => 'applications/transactions/response/PhabricatorApplicationTransactionResponse.php',
@ -1488,6 +1496,7 @@ phutil_register_library_map(array(
'PhabricatorCacheSpec' => 'applications/cache/spec/PhabricatorCacheSpec.php',
'PhabricatorCacheTTLGarbageCollector' => 'applications/cache/garbagecollector/PhabricatorCacheTTLGarbageCollector.php',
'PhabricatorCaches' => 'applications/cache/PhabricatorCaches.php',
'PhabricatorCachesTestCase' => 'applications/cache/__tests__/PhabricatorCachesTestCase.php',
'PhabricatorCalendarApplication' => 'applications/calendar/application/PhabricatorCalendarApplication.php',
'PhabricatorCalendarController' => 'applications/calendar/controller/PhabricatorCalendarController.php',
'PhabricatorCalendarDAO' => 'applications/calendar/storage/PhabricatorCalendarDAO.php',
@ -1790,6 +1799,7 @@ phutil_register_library_map(array(
'PhabricatorEventListener' => 'infrastructure/events/PhabricatorEventListener.php',
'PhabricatorEventType' => 'infrastructure/events/constant/PhabricatorEventType.php',
'PhabricatorExampleEventListener' => 'infrastructure/events/PhabricatorExampleEventListener.php',
'PhabricatorExtendedPolicyInterface' => 'applications/policy/interface/PhabricatorExtendedPolicyInterface.php',
'PhabricatorExtendingPhabricatorConfigOptions' => 'applications/config/option/PhabricatorExtendingPhabricatorConfigOptions.php',
'PhabricatorExtensionsSetupCheck' => 'applications/config/check/PhabricatorExtensionsSetupCheck.php',
'PhabricatorExternalAccount' => 'applications/people/storage/PhabricatorExternalAccount.php',
@ -1970,6 +1980,8 @@ phutil_register_library_map(array(
'PhabricatorListFilterUIExample' => 'applications/uiexample/examples/PhabricatorListFilterUIExample.php',
'PhabricatorLocalDiskFileStorageEngine' => 'applications/files/engine/PhabricatorLocalDiskFileStorageEngine.php',
'PhabricatorLocalTimeTestCase' => 'view/__tests__/PhabricatorLocalTimeTestCase.php',
'PhabricatorLocaleScopeGuard' => 'infrastructure/internationalization/scope/PhabricatorLocaleScopeGuard.php',
'PhabricatorLocaleScopeGuardTestCase' => 'infrastructure/internationalization/scope/__tests__/PhabricatorLocaleScopeGuardTestCase.php',
'PhabricatorLogTriggerAction' => 'infrastructure/daemon/workers/action/PhabricatorLogTriggerAction.php',
'PhabricatorLogoutController' => 'applications/auth/controller/PhabricatorLogoutController.php',
'PhabricatorLunarPhasePolicyRule' => 'applications/policy/rule/PhabricatorLunarPhasePolicyRule.php',
@ -1994,9 +2006,7 @@ phutil_register_library_map(array(
'PhabricatorMacroTransaction' => 'applications/macro/storage/PhabricatorMacroTransaction.php',
'PhabricatorMacroTransactionComment' => 'applications/macro/storage/PhabricatorMacroTransactionComment.php',
'PhabricatorMacroTransactionQuery' => 'applications/macro/query/PhabricatorMacroTransactionQuery.php',
'PhabricatorMacroTransactionType' => 'applications/macro/constants/PhabricatorMacroTransactionType.php',
'PhabricatorMacroViewController' => 'applications/macro/controller/PhabricatorMacroViewController.php',
'PhabricatorMail' => 'applications/metamta/PhabricatorMail.php',
'PhabricatorMailImplementationAdapter' => 'applications/metamta/adapter/PhabricatorMailImplementationAdapter.php',
'PhabricatorMailImplementationAmazonSESAdapter' => 'applications/metamta/adapter/PhabricatorMailImplementationAmazonSESAdapter.php',
'PhabricatorMailImplementationMailgunAdapter' => 'applications/metamta/adapter/PhabricatorMailImplementationMailgunAdapter.php',
@ -2016,16 +2026,8 @@ phutil_register_library_map(array(
'PhabricatorMailReceiverTestCase' => 'applications/metamta/receiver/__tests__/PhabricatorMailReceiverTestCase.php',
'PhabricatorMailReplyHandler' => 'applications/metamta/replyhandler/PhabricatorMailReplyHandler.php',
'PhabricatorMailSetupCheck' => 'applications/config/check/PhabricatorMailSetupCheck.php',
'PhabricatorMailTarget' => 'applications/metamta/replyhandler/PhabricatorMailTarget.php',
'PhabricatorMailgunConfigOptions' => 'applications/config/option/PhabricatorMailgunConfigOptions.php',
'PhabricatorMailingListDatasource' => 'applications/mailinglists/typeahead/PhabricatorMailingListDatasource.php',
'PhabricatorMailingListListPHIDType' => 'applications/mailinglists/phid/PhabricatorMailingListListPHIDType.php',
'PhabricatorMailingListQuery' => 'applications/mailinglists/query/PhabricatorMailingListQuery.php',
'PhabricatorMailingListSearchEngine' => 'applications/mailinglists/query/PhabricatorMailingListSearchEngine.php',
'PhabricatorMailingListsApplication' => 'applications/mailinglists/application/PhabricatorMailingListsApplication.php',
'PhabricatorMailingListsController' => 'applications/mailinglists/controller/PhabricatorMailingListsController.php',
'PhabricatorMailingListsEditController' => 'applications/mailinglists/controller/PhabricatorMailingListsEditController.php',
'PhabricatorMailingListsListController' => 'applications/mailinglists/controller/PhabricatorMailingListsListController.php',
'PhabricatorMailingListsManageCapability' => 'applications/mailinglists/capability/PhabricatorMailingListsManageCapability.php',
'PhabricatorMainMenuSearchView' => 'view/page/menu/PhabricatorMainMenuSearchView.php',
'PhabricatorMainMenuView' => 'view/page/menu/PhabricatorMainMenuView.php',
'PhabricatorManagementWorkflow' => 'infrastructure/management/PhabricatorManagementWorkflow.php',
@ -2134,7 +2136,6 @@ phutil_register_library_map(array(
'PhabricatorOAuthServerTestController' => 'applications/oauthserver/controller/PhabricatorOAuthServerTestController.php',
'PhabricatorOAuthServerTokenController' => 'applications/oauthserver/controller/PhabricatorOAuthServerTokenController.php',
'PhabricatorObjectHandle' => 'applications/phid/PhabricatorObjectHandle.php',
'PhabricatorObjectHandleConstants' => 'applications/phid/handle/const/PhabricatorObjectHandleConstants.php',
'PhabricatorObjectHasAsanaSubtaskEdgeType' => 'applications/doorkeeper/edge/PhabricatorObjectHasAsanaSubtaskEdgeType.php',
'PhabricatorObjectHasAsanaTaskEdgeType' => 'applications/doorkeeper/edge/PhabricatorObjectHasAsanaTaskEdgeType.php',
'PhabricatorObjectHasContributorEdgeType' => 'applications/transactions/edges/PhabricatorObjectHasContributorEdgeType.php',
@ -2242,6 +2243,7 @@ phutil_register_library_map(array(
'PhabricatorPeopleRenameController' => 'applications/people/controller/PhabricatorPeopleRenameController.php',
'PhabricatorPeopleSearchEngine' => 'applications/people/query/PhabricatorPeopleSearchEngine.php',
'PhabricatorPeopleTestDataGenerator' => 'applications/people/lipsum/PhabricatorPeopleTestDataGenerator.php',
'PhabricatorPeopleTransactionQuery' => 'applications/people/query/PhabricatorPeopleTransactionQuery.php',
'PhabricatorPeopleUserFunctionDatasource' => 'applications/people/typeahead/PhabricatorPeopleUserFunctionDatasource.php',
'PhabricatorPeopleUserPHIDType' => 'applications/people/phid/PhabricatorPeopleUserPHIDType.php',
'PhabricatorPeopleWelcomeController' => 'applications/people/controller/PhabricatorPeopleWelcomeController.php',
@ -2381,7 +2383,6 @@ phutil_register_library_map(array(
'PhabricatorRemarkupFigletBlockInterpreter' => 'infrastructure/markup/interpreter/PhabricatorRemarkupFigletBlockInterpreter.php',
'PhabricatorRemarkupGraphvizBlockInterpreter' => 'infrastructure/markup/interpreter/PhabricatorRemarkupGraphvizBlockInterpreter.php',
'PhabricatorRemarkupUIExample' => 'applications/uiexample/examples/PhabricatorRemarkupUIExample.php',
'PhabricatorRepositoriesApplication' => 'applications/repository/application/PhabricatorRepositoriesApplication.php',
'PhabricatorRepositoriesSetupCheck' => 'applications/config/check/PhabricatorRepositoriesSetupCheck.php',
'PhabricatorRepository' => 'applications/repository/storage/PhabricatorRepository.php',
'PhabricatorRepositoryArcanistProject' => 'applications/repository/storage/PhabricatorRepositoryArcanistProject.php',
@ -2400,7 +2401,6 @@ phutil_register_library_map(array(
'PhabricatorRepositoryCommitRef' => 'applications/repository/engine/PhabricatorRepositoryCommitRef.php',
'PhabricatorRepositoryCommitSearchIndexer' => 'applications/repository/search/PhabricatorRepositoryCommitSearchIndexer.php',
'PhabricatorRepositoryConfigOptions' => 'applications/repository/config/PhabricatorRepositoryConfigOptions.php',
'PhabricatorRepositoryController' => 'applications/repository/controller/PhabricatorRepositoryController.php',
'PhabricatorRepositoryDAO' => 'applications/repository/storage/PhabricatorRepositoryDAO.php',
'PhabricatorRepositoryDiscoveryEngine' => 'applications/repository/engine/PhabricatorRepositoryDiscoveryEngine.php',
'PhabricatorRepositoryEditor' => 'applications/repository/editor/PhabricatorRepositoryEditor.php',
@ -2409,7 +2409,6 @@ phutil_register_library_map(array(
'PhabricatorRepositoryGitCommitMessageParserWorker' => 'applications/repository/worker/commitmessageparser/PhabricatorRepositoryGitCommitMessageParserWorker.php',
'PhabricatorRepositoryGraphCache' => 'applications/repository/graphcache/PhabricatorRepositoryGraphCache.php',
'PhabricatorRepositoryGraphStream' => 'applications/repository/daemon/PhabricatorRepositoryGraphStream.php',
'PhabricatorRepositoryListController' => 'applications/repository/controller/PhabricatorRepositoryListController.php',
'PhabricatorRepositoryManagementCacheWorkflow' => 'applications/repository/management/PhabricatorRepositoryManagementCacheWorkflow.php',
'PhabricatorRepositoryManagementDiscoverWorkflow' => 'applications/repository/management/PhabricatorRepositoryManagementDiscoverWorkflow.php',
'PhabricatorRepositoryManagementEditWorkflow' => 'applications/repository/management/PhabricatorRepositoryManagementEditWorkflow.php',
@ -2494,30 +2493,46 @@ phutil_register_library_map(array(
'PhabricatorSearchApplicationStorageEnginePanel' => 'applications/search/applicationpanel/PhabricatorSearchApplicationStorageEnginePanel.php',
'PhabricatorSearchAttachController' => 'applications/search/controller/PhabricatorSearchAttachController.php',
'PhabricatorSearchBaseController' => 'applications/search/controller/PhabricatorSearchBaseController.php',
'PhabricatorSearchCheckboxesField' => 'applications/search/field/PhabricatorSearchCheckboxesField.php',
'PhabricatorSearchConfigOptions' => 'applications/search/config/PhabricatorSearchConfigOptions.php',
'PhabricatorSearchController' => 'applications/search/controller/PhabricatorSearchController.php',
'PhabricatorSearchCustomFieldProxyField' => 'applications/search/field/PhabricatorSearchCustomFieldProxyField.php',
'PhabricatorSearchDAO' => 'applications/search/storage/PhabricatorSearchDAO.php',
'PhabricatorSearchDatasource' => 'applications/search/typeahead/PhabricatorSearchDatasource.php',
'PhabricatorSearchDatasourceField' => 'applications/search/field/PhabricatorSearchDatasourceField.php',
'PhabricatorSearchDateField' => 'applications/search/field/PhabricatorSearchDateField.php',
'PhabricatorSearchDeleteController' => 'applications/search/controller/PhabricatorSearchDeleteController.php',
'PhabricatorSearchDocument' => 'applications/search/storage/document/PhabricatorSearchDocument.php',
'PhabricatorSearchDocumentField' => 'applications/search/storage/document/PhabricatorSearchDocumentField.php',
'PhabricatorSearchDocumentFieldType' => 'applications/search/constants/PhabricatorSearchDocumentFieldType.php',
'PhabricatorSearchDocumentIndexer' => 'applications/search/index/PhabricatorSearchDocumentIndexer.php',
'PhabricatorSearchDocumentQuery' => 'applications/search/query/PhabricatorSearchDocumentQuery.php',
'PhabricatorSearchDocumentRelationship' => 'applications/search/storage/document/PhabricatorSearchDocumentRelationship.php',
'PhabricatorSearchDocumentTypeDatasource' => 'applications/search/typeahead/PhabricatorSearchDocumentTypeDatasource.php',
'PhabricatorSearchEditController' => 'applications/search/controller/PhabricatorSearchEditController.php',
'PhabricatorSearchEngine' => 'applications/search/engine/PhabricatorSearchEngine.php',
'PhabricatorSearchField' => 'applications/search/constants/PhabricatorSearchField.php',
'PhabricatorSearchField' => 'applications/search/field/PhabricatorSearchField.php',
'PhabricatorSearchHovercardController' => 'applications/search/controller/PhabricatorSearchHovercardController.php',
'PhabricatorSearchIndexer' => 'applications/search/index/PhabricatorSearchIndexer.php',
'PhabricatorSearchManagementIndexWorkflow' => 'applications/search/management/PhabricatorSearchManagementIndexWorkflow.php',
'PhabricatorSearchManagementInitWorkflow' => 'applications/search/management/PhabricatorSearchManagementInitWorkflow.php',
'PhabricatorSearchManagementWorkflow' => 'applications/search/management/PhabricatorSearchManagementWorkflow.php',
'PhabricatorSearchOrderController' => 'applications/search/controller/PhabricatorSearchOrderController.php',
'PhabricatorSearchOrderField' => 'applications/search/field/PhabricatorSearchOrderField.php',
'PhabricatorSearchOwnersField' => 'applications/search/field/PhabricatorSearchOwnersField.php',
'PhabricatorSearchPreferencesSettingsPanel' => 'applications/settings/panel/PhabricatorSearchPreferencesSettingsPanel.php',
'PhabricatorSearchProjectsField' => 'applications/search/field/PhabricatorSearchProjectsField.php',
'PhabricatorSearchRelationship' => 'applications/search/constants/PhabricatorSearchRelationship.php',
'PhabricatorSearchResultView' => 'applications/search/view/PhabricatorSearchResultView.php',
'PhabricatorSearchSelectController' => 'applications/search/controller/PhabricatorSearchSelectController.php',
'PhabricatorSearchSelectField' => 'applications/search/field/PhabricatorSearchSelectField.php',
'PhabricatorSearchSpacesField' => 'applications/search/field/PhabricatorSearchSpacesField.php',
'PhabricatorSearchStringListField' => 'applications/search/field/PhabricatorSearchStringListField.php',
'PhabricatorSearchSubscribersField' => 'applications/search/field/PhabricatorSearchSubscribersField.php',
'PhabricatorSearchTextField' => 'applications/search/field/PhabricatorSearchTextField.php',
'PhabricatorSearchThreeStateField' => 'applications/search/field/PhabricatorSearchThreeStateField.php',
'PhabricatorSearchTokenizerField' => 'applications/search/field/PhabricatorSearchTokenizerField.php',
'PhabricatorSearchUsersField' => 'applications/search/field/PhabricatorSearchUsersField.php',
'PhabricatorSearchWorker' => 'applications/search/worker/PhabricatorSearchWorker.php',
'PhabricatorSecurityConfigOptions' => 'applications/config/option/PhabricatorSecurityConfigOptions.php',
'PhabricatorSecuritySetupCheck' => 'applications/config/check/PhabricatorSecuritySetupCheck.php',
@ -2557,6 +2572,27 @@ phutil_register_library_map(array(
'PhabricatorSlugTestCase' => 'infrastructure/util/__tests__/PhabricatorSlugTestCase.php',
'PhabricatorSortTableUIExample' => 'applications/uiexample/examples/PhabricatorSortTableUIExample.php',
'PhabricatorSourceCodeView' => 'view/layout/PhabricatorSourceCodeView.php',
'PhabricatorSpacesApplication' => 'applications/spaces/application/PhabricatorSpacesApplication.php',
'PhabricatorSpacesCapabilityCreateSpaces' => 'applications/spaces/capability/PhabricatorSpacesCapabilityCreateSpaces.php',
'PhabricatorSpacesCapabilityDefaultEdit' => 'applications/spaces/capability/PhabricatorSpacesCapabilityDefaultEdit.php',
'PhabricatorSpacesCapabilityDefaultView' => 'applications/spaces/capability/PhabricatorSpacesCapabilityDefaultView.php',
'PhabricatorSpacesControl' => 'applications/spaces/view/PhabricatorSpacesControl.php',
'PhabricatorSpacesController' => 'applications/spaces/controller/PhabricatorSpacesController.php',
'PhabricatorSpacesDAO' => 'applications/spaces/storage/PhabricatorSpacesDAO.php',
'PhabricatorSpacesEditController' => 'applications/spaces/controller/PhabricatorSpacesEditController.php',
'PhabricatorSpacesInterface' => 'applications/spaces/interface/PhabricatorSpacesInterface.php',
'PhabricatorSpacesListController' => 'applications/spaces/controller/PhabricatorSpacesListController.php',
'PhabricatorSpacesNamespace' => 'applications/spaces/storage/PhabricatorSpacesNamespace.php',
'PhabricatorSpacesNamespaceDatasource' => 'applications/spaces/typeahead/PhabricatorSpacesNamespaceDatasource.php',
'PhabricatorSpacesNamespaceEditor' => 'applications/spaces/editor/PhabricatorSpacesNamespaceEditor.php',
'PhabricatorSpacesNamespacePHIDType' => 'applications/spaces/phid/PhabricatorSpacesNamespacePHIDType.php',
'PhabricatorSpacesNamespaceQuery' => 'applications/spaces/query/PhabricatorSpacesNamespaceQuery.php',
'PhabricatorSpacesNamespaceSearchEngine' => 'applications/spaces/query/PhabricatorSpacesNamespaceSearchEngine.php',
'PhabricatorSpacesNamespaceTransaction' => 'applications/spaces/storage/PhabricatorSpacesNamespaceTransaction.php',
'PhabricatorSpacesNamespaceTransactionQuery' => 'applications/spaces/query/PhabricatorSpacesNamespaceTransactionQuery.php',
'PhabricatorSpacesRemarkupRule' => 'applications/spaces/remarkup/PhabricatorSpacesRemarkupRule.php',
'PhabricatorSpacesTestCase' => 'applications/spaces/__tests__/PhabricatorSpacesTestCase.php',
'PhabricatorSpacesViewController' => 'applications/spaces/controller/PhabricatorSpacesViewController.php',
'PhabricatorStandardCustomField' => 'infrastructure/customfield/standard/PhabricatorStandardCustomField.php',
'PhabricatorStandardCustomFieldBool' => 'infrastructure/customfield/standard/PhabricatorStandardCustomFieldBool.php',
'PhabricatorStandardCustomFieldCredential' => 'infrastructure/customfield/standard/PhabricatorStandardCustomFieldCredential.php',
@ -2814,7 +2850,6 @@ phutil_register_library_map(array(
'PhluxVariableQuery' => 'applications/phlux/query/PhluxVariableQuery.php',
'PhluxViewController' => 'applications/phlux/controller/PhluxViewController.php',
'PholioActionMenuEventListener' => 'applications/pholio/event/PholioActionMenuEventListener.php',
'PholioConstants' => 'applications/pholio/constants/PholioConstants.php',
'PholioController' => 'applications/pholio/controller/PholioController.php',
'PholioDAO' => 'applications/pholio/storage/PholioDAO.php',
'PholioDefaultEditCapability' => 'applications/pholio/capability/PholioDefaultEditCapability.php',
@ -2846,7 +2881,6 @@ phutil_register_library_map(array(
'PholioTransaction' => 'applications/pholio/storage/PholioTransaction.php',
'PholioTransactionComment' => 'applications/pholio/storage/PholioTransactionComment.php',
'PholioTransactionQuery' => 'applications/pholio/query/PholioTransactionQuery.php',
'PholioTransactionType' => 'applications/pholio/constants/PholioTransactionType.php',
'PholioTransactionView' => 'applications/pholio/view/PholioTransactionView.php',
'PholioUploadedImageView' => 'applications/pholio/view/PholioUploadedImageView.php',
'PhortuneAccount' => 'applications/phortune/storage/PhortuneAccount.php',
@ -3002,7 +3036,6 @@ phutil_register_library_map(array(
'PhrequentUIEventListener' => 'applications/phrequent/event/PhrequentUIEventListener.php',
'PhrequentUserTime' => 'applications/phrequent/storage/PhrequentUserTime.php',
'PhrequentUserTimeQuery' => 'applications/phrequent/query/PhrequentUserTimeQuery.php',
'PhrictionActionConstants' => 'applications/phriction/constants/PhrictionActionConstants.php',
'PhrictionChangeType' => 'applications/phriction/constants/PhrictionChangeType.php',
'PhrictionConduitAPIMethod' => 'applications/phriction/conduit/PhrictionConduitAPIMethod.php',
'PhrictionConstants' => 'applications/phriction/constants/PhrictionConstants.php',
@ -3422,7 +3455,6 @@ phutil_register_library_map(array(
'AuditConduitAPIMethod' => 'ConduitAPIMethod',
'AuditQueryConduitAPIMethod' => 'AuditConduitAPIMethod',
'AuthManageProvidersCapability' => 'PhabricatorPolicyCapability',
'CalendarColors' => 'CalendarConstants',
'CalendarTimeUtilTestCase' => 'PhabricatorTestCase',
'CelerityManagementMapWorkflow' => 'CelerityManagementWorkflow',
'CelerityManagementWorkflow' => 'PhabricatorManagementWorkflow',
@ -3507,7 +3539,6 @@ phutil_register_library_map(array(
'ConpherenceTransaction' => 'PhabricatorApplicationTransaction',
'ConpherenceTransactionComment' => 'PhabricatorApplicationTransactionComment',
'ConpherenceTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
'ConpherenceTransactionType' => 'ConpherenceConstants',
'ConpherenceTransactionView' => 'AphrontView',
'ConpherenceUpdateActions' => 'ConpherenceConstants',
'ConpherenceUpdateController' => 'ConpherenceController',
@ -3660,6 +3691,7 @@ phutil_register_library_map(array(
'DifferentialDAO',
'PhabricatorTokenReceiverInterface',
'PhabricatorPolicyInterface',
'PhabricatorExtendedPolicyInterface',
'PhabricatorFlaggableInterface',
'PhrequentTrackableInterface',
'HarbormasterBuildableInterface',
@ -3799,11 +3831,13 @@ phutil_register_library_map(array(
'DiffusionPathQueryTestCase' => 'PhabricatorTestCase',
'DiffusionPathTreeController' => 'DiffusionController',
'DiffusionPathValidateController' => 'DiffusionController',
'DiffusionPhpExternalSymbolsSource' => 'DiffusionExternalSymbolsSource',
'DiffusionPushCapability' => 'PhabricatorPolicyCapability',
'DiffusionPushEventViewController' => 'DiffusionPushLogController',
'DiffusionPushLogController' => 'DiffusionController',
'DiffusionPushLogListController' => 'DiffusionPushLogController',
'DiffusionPushLogListView' => 'AphrontView',
'DiffusionPythonExternalSymbolsSource' => 'DiffusionExternalSymbolsSource',
'DiffusionQuery' => 'PhabricatorQuery',
'DiffusionQueryCommitsConduitAPIMethod' => 'DiffusionConduitAPIMethod',
'DiffusionQueryConduitAPIMethod' => 'DiffusionConduitAPIMethod',
@ -3868,11 +3902,13 @@ phutil_register_library_map(array(
'DivinerAtomPHIDType' => 'PhabricatorPHIDType',
'DivinerAtomQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
'DivinerAtomSearchEngine' => 'PhabricatorApplicationSearchEngine',
'DivinerAtomSearchIndexer' => 'PhabricatorSearchDocumentIndexer',
'DivinerAtomizeWorkflow' => 'DivinerWorkflow',
'DivinerBookController' => 'DivinerController',
'DivinerBookItemView' => 'AphrontTagView',
'DivinerBookPHIDType' => 'PhabricatorPHIDType',
'DivinerBookQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
'DivinerBookSearchIndexer' => 'PhabricatorSearchDocumentIndexer',
'DivinerController' => 'PhabricatorController',
'DivinerDAO' => 'PhabricatorLiskDAO',
'DivinerDefaultRenderer' => 'DivinerRenderer',
@ -3902,6 +3938,7 @@ phutil_register_library_map(array(
'DivinerSymbolRemarkupRule' => 'PhutilRemarkupRule',
'DivinerWorkflow' => 'PhabricatorManagementWorkflow',
'DoorkeeperAsanaFeedWorker' => 'DoorkeeperFeedWorker',
'DoorkeeperAsanaRemarkupRule' => 'DoorkeeperRemarkupRule',
'DoorkeeperBridge' => 'Phobject',
'DoorkeeperBridgeAsana' => 'DoorkeeperBridge',
'DoorkeeperBridgeJIRA' => 'DoorkeeperBridge',
@ -3915,11 +3952,10 @@ phutil_register_library_map(array(
'DoorkeeperFeedWorker' => 'FeedPushWorker',
'DoorkeeperImportEngine' => 'Phobject',
'DoorkeeperJIRAFeedWorker' => 'DoorkeeperFeedWorker',
'DoorkeeperJIRARemarkupRule' => 'DoorkeeperRemarkupRule',
'DoorkeeperMissingLinkException' => 'Exception',
'DoorkeeperObjectRef' => 'Phobject',
'DoorkeeperRemarkupRule' => 'PhutilRemarkupRule',
'DoorkeeperRemarkupRuleAsana' => 'DoorkeeperRemarkupRule',
'DoorkeeperRemarkupRuleJIRA' => 'DoorkeeperRemarkupRule',
'DoorkeeperSchemaSpec' => 'PhabricatorConfigSchemaSpec',
'DoorkeeperTagView' => 'AphrontView',
'DoorkeeperTagsController' => 'PhabricatorController',
@ -4291,7 +4327,6 @@ phutil_register_library_map(array(
'LegalpadTransaction' => 'PhabricatorApplicationTransaction',
'LegalpadTransactionComment' => 'PhabricatorApplicationTransactionComment',
'LegalpadTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
'LegalpadTransactionType' => 'LegalpadConstants',
'LegalpadTransactionView' => 'PhabricatorApplicationTransactionView',
'LiskChunkTestCase' => 'PhabricatorTestCase',
'LiskDAOTestCase' => 'PhabricatorTestCase',
@ -4400,7 +4435,6 @@ phutil_register_library_map(array(
'MetaMTAEmailTransactionCommand' => 'Phobject',
'MetaMTAMailReceivedGarbageCollector' => 'PhabricatorGarbageCollector',
'MetaMTAMailSentGarbageCollector' => 'PhabricatorGarbageCollector',
'MetaMTANotificationType' => 'MetaMTAConstants',
'MetaMTAReceivedMailStatus' => 'MetaMTAConstants',
'MultimeterContext' => 'MultimeterDimension',
'MultimeterController' => 'PhabricatorController',
@ -4433,17 +4467,24 @@ phutil_register_library_map(array(
'NuanceQueue' => array(
'NuanceDAO',
'PhabricatorPolicyInterface',
'PhabricatorApplicationTransactionInterface',
),
'NuanceQueueEditController' => 'NuanceController',
'NuanceQueueEditor' => 'PhabricatorApplicationTransactionEditor',
'NuanceQueueItem' => 'NuanceDAO',
'NuanceQueueListController' => 'NuanceController',
'NuanceQueuePHIDType' => 'PhabricatorPHIDType',
'NuanceQueueQuery' => 'NuanceQuery',
'NuanceQueueSearchEngine' => 'PhabricatorApplicationSearchEngine',
'NuanceQueueTransaction' => 'NuanceTransaction',
'NuanceQueueTransactionComment' => 'PhabricatorApplicationTransactionComment',
'NuanceQueueTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
'NuanceQueueViewController' => 'NuanceController',
'NuanceRequestor' => 'NuanceDAO',
'NuanceRequestor' => array(
'NuanceDAO',
'PhabricatorPolicyInterface',
'PhabricatorApplicationTransactionInterface',
),
'NuanceRequestorEditController' => 'NuanceController',
'NuanceRequestorEditor' => 'PhabricatorApplicationTransactionEditor',
'NuanceRequestorPHIDType' => 'PhabricatorPHIDType',
@ -4459,14 +4500,18 @@ phutil_register_library_map(array(
'PhabricatorApplicationTransactionInterface',
'PhabricatorPolicyInterface',
),
'NuanceSourceActionController' => 'NuanceController',
'NuanceSourceCreateController' => 'NuanceController',
'NuanceSourceDefaultEditCapability' => 'PhabricatorPolicyCapability',
'NuanceSourceDefaultViewCapability' => 'PhabricatorPolicyCapability',
'NuanceSourceDefinition' => 'Phobject',
'NuanceSourceEditController' => 'NuanceController',
'NuanceSourceEditor' => 'PhabricatorApplicationTransactionEditor',
'NuanceSourceListController' => 'NuanceController',
'NuanceSourceManageCapability' => 'PhabricatorPolicyCapability',
'NuanceSourcePHIDType' => 'PhabricatorPHIDType',
'NuanceSourceQuery' => 'NuanceQuery',
'NuanceSourceSearchEngine' => 'PhabricatorApplicationSearchEngine',
'NuanceSourceTransaction' => 'NuanceTransaction',
'NuanceSourceTransactionComment' => 'PhabricatorApplicationTransactionComment',
'NuanceSourceTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
@ -4541,6 +4586,7 @@ phutil_register_library_map(array(
'PHUIPropertyListExample' => 'PhabricatorUIExample',
'PHUIPropertyListView' => 'AphrontView',
'PHUIRemarkupPreviewPanel' => 'AphrontTagView',
'PHUISpacesNamespaceContextView' => 'AphrontView',
'PHUIStatusItemView' => 'AphrontTagView',
'PHUIStatusListView' => 'AphrontTagView',
'PHUITagExample' => 'PhabricatorUIExample',
@ -4639,6 +4685,7 @@ phutil_register_library_map(array(
'PhabricatorApplicationPanelController' => 'PhabricatorApplicationsController',
'PhabricatorApplicationQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
'PhabricatorApplicationSearchController' => 'PhabricatorSearchBaseController',
'PhabricatorApplicationSearchEngine' => 'Phobject',
'PhabricatorApplicationStatusView' => 'AphrontView',
'PhabricatorApplicationTransaction' => array(
'PhabricatorLiskDAO',
@ -4665,6 +4712,7 @@ phutil_register_library_map(array(
'PhabricatorApplicationTransactionFeedStory' => 'PhabricatorFeedStory',
'PhabricatorApplicationTransactionNoEffectException' => 'Exception',
'PhabricatorApplicationTransactionNoEffectResponse' => 'AphrontProxyResponse',
'PhabricatorApplicationTransactionPublishWorker' => 'PhabricatorWorker',
'PhabricatorApplicationTransactionQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
'PhabricatorApplicationTransactionReplyHandler' => 'PhabricatorMailReplyHandler',
'PhabricatorApplicationTransactionResponse' => 'AphrontProxyResponse',
@ -4830,6 +4878,7 @@ phutil_register_library_map(array(
'PhabricatorCacheSetupCheck' => 'PhabricatorSetupCheck',
'PhabricatorCacheSpec' => 'Phobject',
'PhabricatorCacheTTLGarbageCollector' => 'PhabricatorGarbageCollector',
'PhabricatorCachesTestCase' => 'PhabricatorTestCase',
'PhabricatorCalendarApplication' => 'PhabricatorApplication',
'PhabricatorCalendarController' => 'PhabricatorController',
'PhabricatorCalendarDAO' => 'PhabricatorLiskDAO',
@ -5373,6 +5422,8 @@ phutil_register_library_map(array(
'PhabricatorListFilterUIExample' => 'PhabricatorUIExample',
'PhabricatorLocalDiskFileStorageEngine' => 'PhabricatorFileStorageEngine',
'PhabricatorLocalTimeTestCase' => 'PhabricatorTestCase',
'PhabricatorLocaleScopeGuard' => 'Phobject',
'PhabricatorLocaleScopeGuardTestCase' => 'PhabricatorTestCase',
'PhabricatorLogTriggerAction' => 'PhabricatorTriggerAction',
'PhabricatorLogoutController' => 'PhabricatorAuthController',
'PhabricatorLunarPhasePolicyRule' => 'PhabricatorPolicyRule',
@ -5414,16 +5465,8 @@ phutil_register_library_map(array(
'PhabricatorMailManagementWorkflow' => 'PhabricatorManagementWorkflow',
'PhabricatorMailReceiverTestCase' => 'PhabricatorTestCase',
'PhabricatorMailSetupCheck' => 'PhabricatorSetupCheck',
'PhabricatorMailTarget' => 'Phobject',
'PhabricatorMailgunConfigOptions' => 'PhabricatorApplicationConfigOptions',
'PhabricatorMailingListDatasource' => 'PhabricatorTypeaheadDatasource',
'PhabricatorMailingListListPHIDType' => 'PhabricatorPHIDType',
'PhabricatorMailingListQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
'PhabricatorMailingListSearchEngine' => 'PhabricatorApplicationSearchEngine',
'PhabricatorMailingListsApplication' => 'PhabricatorApplication',
'PhabricatorMailingListsController' => 'PhabricatorController',
'PhabricatorMailingListsEditController' => 'PhabricatorMailingListsController',
'PhabricatorMailingListsListController' => 'PhabricatorMailingListsController',
'PhabricatorMailingListsManageCapability' => 'PhabricatorPolicyCapability',
'PhabricatorMainMenuSearchView' => 'AphrontView',
'PhabricatorMainMenuView' => 'AphrontView',
'PhabricatorManagementWorkflow' => 'PhutilArgumentWorkflow',
@ -5457,11 +5500,7 @@ phutil_register_library_map(array(
'PhabricatorMetaMTAMailableDatasource' => 'PhabricatorTypeaheadCompositeDatasource',
'PhabricatorMetaMTAMailableFunctionDatasource' => 'PhabricatorTypeaheadCompositeDatasource',
'PhabricatorMetaMTAMailgunReceiveController' => 'PhabricatorMetaMTAController',
'PhabricatorMetaMTAMailingList' => array(
'PhabricatorMetaMTADAO',
'PhabricatorPolicyInterface',
'PhabricatorDestructibleInterface',
),
'PhabricatorMetaMTAMailingList' => 'PhabricatorMetaMTADAO',
'PhabricatorMetaMTAMemberQuery' => 'PhabricatorQuery',
'PhabricatorMetaMTAPermanentFailureException' => 'Exception',
'PhabricatorMetaMTAReceivedMail' => 'PhabricatorMetaMTADAO',
@ -5601,6 +5640,7 @@ phutil_register_library_map(array(
'PhabricatorProjectInterface',
'PhabricatorDestructibleInterface',
'PhabricatorApplicationTransactionInterface',
'PhabricatorSpacesInterface',
),
'PhabricatorPasteApplication' => 'PhabricatorApplication',
'PhabricatorPasteCommentController' => 'PhabricatorPasteController',
@ -5651,6 +5691,7 @@ phutil_register_library_map(array(
'PhabricatorPeopleRenameController' => 'PhabricatorPeopleController',
'PhabricatorPeopleSearchEngine' => 'PhabricatorApplicationSearchEngine',
'PhabricatorPeopleTestDataGenerator' => 'PhabricatorTestDataGenerator',
'PhabricatorPeopleTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
'PhabricatorPeopleUserFunctionDatasource' => 'PhabricatorTypeaheadCompositeDatasource',
'PhabricatorPeopleUserPHIDType' => 'PhabricatorPHIDType',
'PhabricatorPeopleWelcomeController' => 'PhabricatorPeopleController',
@ -5699,7 +5740,10 @@ phutil_register_library_map(array(
'PhabricatorPolicyPHIDTypePolicy' => 'PhabricatorPHIDType',
'PhabricatorPolicyQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
'PhabricatorPolicyTestCase' => 'PhabricatorTestCase',
'PhabricatorPolicyTestObject' => 'PhabricatorPolicyInterface',
'PhabricatorPolicyTestObject' => array(
'PhabricatorPolicyInterface',
'PhabricatorExtendedPolicyInterface',
),
'PhabricatorPolicyType' => 'PhabricatorPolicyConstants',
'PhabricatorPonderApplication' => 'PhabricatorApplication',
'PhabricatorProject' => array(
@ -5812,7 +5856,6 @@ phutil_register_library_map(array(
'PhabricatorRemarkupFigletBlockInterpreter' => 'PhutilRemarkupBlockInterpreter',
'PhabricatorRemarkupGraphvizBlockInterpreter' => 'PhutilRemarkupBlockInterpreter',
'PhabricatorRemarkupUIExample' => 'PhabricatorUIExample',
'PhabricatorRepositoriesApplication' => 'PhabricatorApplication',
'PhabricatorRepositoriesSetupCheck' => 'PhabricatorSetupCheck',
'PhabricatorRepository' => array(
'PhabricatorRepositoryDAO',
@ -5856,14 +5899,12 @@ phutil_register_library_map(array(
'PhabricatorRepositoryCommitParserWorker' => 'PhabricatorWorker',
'PhabricatorRepositoryCommitSearchIndexer' => 'PhabricatorSearchDocumentIndexer',
'PhabricatorRepositoryConfigOptions' => 'PhabricatorApplicationConfigOptions',
'PhabricatorRepositoryController' => 'PhabricatorController',
'PhabricatorRepositoryDAO' => 'PhabricatorLiskDAO',
'PhabricatorRepositoryDiscoveryEngine' => 'PhabricatorRepositoryEngine',
'PhabricatorRepositoryEditor' => 'PhabricatorApplicationTransactionEditor',
'PhabricatorRepositoryGitCommitChangeParserWorker' => 'PhabricatorRepositoryCommitChangeParserWorker',
'PhabricatorRepositoryGitCommitMessageParserWorker' => 'PhabricatorRepositoryCommitMessageParserWorker',
'PhabricatorRepositoryGraphStream' => 'Phobject',
'PhabricatorRepositoryListController' => 'PhabricatorRepositoryController',
'PhabricatorRepositoryManagementCacheWorkflow' => 'PhabricatorRepositoryManagementWorkflow',
'PhabricatorRepositoryManagementDiscoverWorkflow' => 'PhabricatorRepositoryManagementWorkflow',
'PhabricatorRepositoryManagementEditWorkflow' => 'PhabricatorRepositoryManagementWorkflow',
@ -5957,26 +5998,43 @@ phutil_register_library_map(array(
'PhabricatorSearchApplicationStorageEnginePanel' => 'PhabricatorApplicationConfigurationPanel',
'PhabricatorSearchAttachController' => 'PhabricatorSearchBaseController',
'PhabricatorSearchBaseController' => 'PhabricatorController',
'PhabricatorSearchCheckboxesField' => 'PhabricatorSearchField',
'PhabricatorSearchConfigOptions' => 'PhabricatorApplicationConfigOptions',
'PhabricatorSearchController' => 'PhabricatorSearchBaseController',
'PhabricatorSearchCustomFieldProxyField' => 'PhabricatorSearchField',
'PhabricatorSearchDAO' => 'PhabricatorLiskDAO',
'PhabricatorSearchDatasource' => 'PhabricatorTypeaheadCompositeDatasource',
'PhabricatorSearchDatasourceField' => 'PhabricatorSearchTokenizerField',
'PhabricatorSearchDateField' => 'PhabricatorSearchField',
'PhabricatorSearchDeleteController' => 'PhabricatorSearchBaseController',
'PhabricatorSearchDocument' => 'PhabricatorSearchDAO',
'PhabricatorSearchDocumentField' => 'PhabricatorSearchDAO',
'PhabricatorSearchDocumentFieldType' => 'Phobject',
'PhabricatorSearchDocumentIndexer' => 'Phobject',
'PhabricatorSearchDocumentQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
'PhabricatorSearchDocumentRelationship' => 'PhabricatorSearchDAO',
'PhabricatorSearchDocumentTypeDatasource' => 'PhabricatorTypeaheadDatasource',
'PhabricatorSearchEditController' => 'PhabricatorSearchBaseController',
'PhabricatorSearchField' => 'Phobject',
'PhabricatorSearchHovercardController' => 'PhabricatorSearchBaseController',
'PhabricatorSearchManagementIndexWorkflow' => 'PhabricatorSearchManagementWorkflow',
'PhabricatorSearchManagementInitWorkflow' => 'PhabricatorSearchManagementWorkflow',
'PhabricatorSearchManagementWorkflow' => 'PhabricatorManagementWorkflow',
'PhabricatorSearchOrderController' => 'PhabricatorSearchBaseController',
'PhabricatorSearchOrderField' => 'PhabricatorSearchField',
'PhabricatorSearchOwnersField' => 'PhabricatorSearchTokenizerField',
'PhabricatorSearchPreferencesSettingsPanel' => 'PhabricatorSettingsPanel',
'PhabricatorSearchProjectsField' => 'PhabricatorSearchTokenizerField',
'PhabricatorSearchResultView' => 'AphrontView',
'PhabricatorSearchSelectController' => 'PhabricatorSearchBaseController',
'PhabricatorSearchSelectField' => 'PhabricatorSearchField',
'PhabricatorSearchSpacesField' => 'PhabricatorSearchTokenizerField',
'PhabricatorSearchStringListField' => 'PhabricatorSearchField',
'PhabricatorSearchSubscribersField' => 'PhabricatorSearchTokenizerField',
'PhabricatorSearchTextField' => 'PhabricatorSearchField',
'PhabricatorSearchThreeStateField' => 'PhabricatorSearchField',
'PhabricatorSearchTokenizerField' => 'PhabricatorSearchField',
'PhabricatorSearchUsersField' => 'PhabricatorSearchTokenizerField',
'PhabricatorSearchWorker' => 'PhabricatorWorker',
'PhabricatorSecurityConfigOptions' => 'PhabricatorApplicationConfigOptions',
'PhabricatorSecuritySetupCheck' => 'PhabricatorSetupCheck',
@ -6021,6 +6079,32 @@ phutil_register_library_map(array(
'PhabricatorSlugTestCase' => 'PhabricatorTestCase',
'PhabricatorSortTableUIExample' => 'PhabricatorUIExample',
'PhabricatorSourceCodeView' => 'AphrontView',
'PhabricatorSpacesApplication' => 'PhabricatorApplication',
'PhabricatorSpacesCapabilityCreateSpaces' => 'PhabricatorPolicyCapability',
'PhabricatorSpacesCapabilityDefaultEdit' => 'PhabricatorPolicyCapability',
'PhabricatorSpacesCapabilityDefaultView' => 'PhabricatorPolicyCapability',
'PhabricatorSpacesControl' => 'AphrontFormControl',
'PhabricatorSpacesController' => 'PhabricatorController',
'PhabricatorSpacesDAO' => 'PhabricatorLiskDAO',
'PhabricatorSpacesEditController' => 'PhabricatorSpacesController',
'PhabricatorSpacesInterface' => 'PhabricatorPHIDInterface',
'PhabricatorSpacesListController' => 'PhabricatorSpacesController',
'PhabricatorSpacesNamespace' => array(
'PhabricatorSpacesDAO',
'PhabricatorPolicyInterface',
'PhabricatorApplicationTransactionInterface',
'PhabricatorDestructibleInterface',
),
'PhabricatorSpacesNamespaceDatasource' => 'PhabricatorTypeaheadDatasource',
'PhabricatorSpacesNamespaceEditor' => 'PhabricatorApplicationTransactionEditor',
'PhabricatorSpacesNamespacePHIDType' => 'PhabricatorPHIDType',
'PhabricatorSpacesNamespaceQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
'PhabricatorSpacesNamespaceSearchEngine' => 'PhabricatorApplicationSearchEngine',
'PhabricatorSpacesNamespaceTransaction' => 'PhabricatorApplicationTransaction',
'PhabricatorSpacesNamespaceTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
'PhabricatorSpacesRemarkupRule' => 'PhabricatorObjectRemarkupRule',
'PhabricatorSpacesTestCase' => 'PhabricatorTestCase',
'PhabricatorSpacesViewController' => 'PhabricatorSpacesController',
'PhabricatorStandardCustomField' => 'PhabricatorCustomField',
'PhabricatorStandardCustomFieldBool' => 'PhabricatorStandardCustomField',
'PhabricatorStandardCustomFieldCredential' => 'PhabricatorStandardCustomField',
@ -6146,6 +6230,7 @@ phutil_register_library_map(array(
'PhabricatorCustomFieldInterface',
'PhabricatorDestructibleInterface',
'PhabricatorSSHPublicKeyInterface',
'PhabricatorApplicationTransactionInterface',
),
'PhabricatorUserBlurbField' => 'PhabricatorUserCustomField',
'PhabricatorUserConfigOptions' => 'PhabricatorApplicationConfigOptions',
@ -6241,6 +6326,7 @@ phutil_register_library_map(array(
'PhameDAO',
'PhabricatorPolicyInterface',
'PhabricatorMarkupInterface',
'PhabricatorApplicationTransactionInterface',
),
'PhameBlogDeleteController' => 'PhameController',
'PhameBlogEditController' => 'PhameController',
@ -6345,7 +6431,6 @@ phutil_register_library_map(array(
'PholioTransaction' => 'PhabricatorApplicationTransaction',
'PholioTransactionComment' => 'PhabricatorApplicationTransactionComment',
'PholioTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
'PholioTransactionType' => 'PholioConstants',
'PholioTransactionView' => 'PhabricatorApplicationTransactionView',
'PholioUploadedImageView' => 'AphrontView',
'PhortuneAccount' => array(
@ -6539,7 +6624,6 @@ phutil_register_library_map(array(
'PhabricatorPolicyInterface',
),
'PhrequentUserTimeQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
'PhrictionActionConstants' => 'PhrictionConstants',
'PhrictionChangeType' => 'PhrictionConstants',
'PhrictionConduitAPIMethod' => 'ConduitAPIMethod',
'PhrictionContent' => array(

View file

@ -80,7 +80,7 @@ abstract class AphrontApplicationConfiguration {
// This is the earliest we can get away with this, we need env config first.
PhabricatorAccessLog::init();
$access_log = PhabricatorAccessLog::getLog();
PhabricatorStartup::setGlobal('log.access', $access_log);
PhabricatorStartup::setAccessLog($access_log);
$access_log->setData(
array(
'R' => AphrontRequest::getHTTPHeader('Referer', '-'),

View file

@ -164,14 +164,6 @@ class AphrontDefaultApplicationConfiguration
return $login_controller->handleRequest($request);
}
$list = $ex->getMoreInfo();
foreach ($list as $key => $item) {
$list[$key] = phutil_tag('li', array(), $item);
}
if ($list) {
$list = phutil_tag('ul', array(), $list);
}
$content = array(
phutil_tag(
'div',
@ -179,17 +171,28 @@ class AphrontDefaultApplicationConfiguration
'class' => 'aphront-policy-rejection',
),
$ex->getRejection()),
phutil_tag(
);
if ($ex->getCapabilityName()) {
$list = $ex->getMoreInfo();
foreach ($list as $key => $item) {
$list[$key] = phutil_tag('li', array(), $item);
}
if ($list) {
$list = phutil_tag('ul', array(), $list);
}
$content[] = phutil_tag(
'div',
array(
'class' => 'aphront-capability-details',
),
pht('Users with the "%s" capability:', $ex->getCapabilityName())),
$list,
);
pht('Users with the "%s" capability:', $ex->getCapabilityName()));
$dialog = new AphrontDialogView();
$dialog
$content[] = $list;
}
$dialog = id(new AphrontDialogView())
->setTitle($ex->getTitle())
->setClass('aphront-access-dialog')
->setUser($user)

View file

@ -75,7 +75,9 @@ final class AphrontHTTPSinkTestCase extends PhabricatorTestCase {
$this->assertEqual(
'for (;;);{"x":"\u003ciframe\u003e"}',
$sink->getEmittedData(),
'JSONResponse should prevent content-sniffing attacks.');
pht(
'%s should prevent content-sniffing attacks.',
'JSONResponse'));
}

View file

@ -87,7 +87,7 @@ final class AlmanacBindingEditController
->appendControl(
id(new AphrontFormTokenizerControl())
->setName('interfacePHIDs')
->setLabel('Interface')
->setLabel(pht('Interface'))
->setLimit(1)
->setDatasource(new AlmanacInterfaceDatasource())
->setValue($v_interface)

View file

@ -37,7 +37,7 @@ final class AlmanacConsoleController extends AlmanacController {
$crumbs->addTextCrumb(pht('Console'));
$box = id(new PHUIObjectBoxView())
->setHeaderText('Console')
->setHeaderText(pht('Console'))
->setObjectList($menu);
return $this->buildApplicationPage(

View file

@ -67,6 +67,7 @@ final class AlmanacDeviceEditor
switch ($xaction->getTransactionType()) {
case AlmanacDeviceTransaction::TYPE_NAME:
return;
case AlmanacDeviceTransaction::TYPE_INTERFACE:
$old = $xaction->getOldValue();
if ($old) {

View file

@ -60,47 +60,35 @@ final class AlmanacServiceQuery
}
protected function loadPage() {
$table = new AlmanacService();
$conn_r = $table->establishConnection('r');
$data = queryfx_all(
$conn_r,
'SELECT service.* FROM %T service %Q %Q %Q %Q',
$table->getTableName(),
$this->buildJoinClause($conn_r),
$this->buildWhereClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
return $table->loadAllFromArray($data);
return $this->loadStandardPage(new AlmanacService());
}
protected function buildJoinClause(AphrontDatabaseConnection $conn_r) {
$joins = array();
protected function buildJoinClauseParts(AphrontDatabaseConnection $conn) {
$joins = parent::buildJoinClauseParts($conn);
if ($this->devicePHIDs !== null) {
$joins[] = qsprintf(
$conn_r,
$conn,
'JOIN %T binding ON service.phid = binding.servicePHID',
id(new AlmanacBinding())->getTableName());
}
return implode(' ', $joins);
return $joins;
}
protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();
protected function buildWhereClauseParts(AphrontDatabaseConnection $conn) {
$where = parent::buildWhereClauseParts($conn);
if ($this->ids !== null) {
$where[] = qsprintf(
$conn_r,
$conn,
'service.id IN (%Ld)',
$this->ids);
}
if ($this->phids !== null) {
$where[] = qsprintf(
$conn_r,
$conn,
'service.phid IN (%Ls)',
$this->phids);
}
@ -112,49 +100,47 @@ final class AlmanacServiceQuery
}
$where[] = qsprintf(
$conn_r,
$conn,
'service.nameIndex IN (%Ls)',
$hashes);
}
if ($this->serviceClasses !== null) {
$where[] = qsprintf(
$conn_r,
$conn,
'service.serviceClass IN (%Ls)',
$this->serviceClasses);
}
if ($this->devicePHIDs !== null) {
$where[] = qsprintf(
$conn_r,
$conn,
'binding.devicePHID IN (%Ls)',
$this->devicePHIDs);
}
if ($this->locked !== null) {
$where[] = qsprintf(
$conn_r,
$conn,
'service.isLocked = %d',
(int)$this->locked);
}
if ($this->namePrefix !== null) {
$where[] = qsprintf(
$conn_r,
$conn,
'service.name LIKE %>',
$this->namePrefix);
}
if ($this->nameSuffix !== null) {
$where[] = qsprintf(
$conn_r,
$conn,
'service.name LIKE %<',
$this->nameSuffix);
}
$where[] = $this->buildPagingClause($conn_r);
return $this->formatWhereClause($where);
return $where;
}
protected function willFilterPage(array $services) {
@ -192,10 +178,14 @@ final class AlmanacServiceQuery
return parent::didFilterPage($services);
}
protected function getPrimaryTableAlias() {
return 'service';
}
public function getOrderableColumns() {
return parent::getOrderableColumns() + array(
'name' => array(
'table' => 'service',
'table' => $this->getPrimaryTableAlias(),
'column' => 'name',
'type' => 'string',
'unique' => true,

View file

@ -11,30 +11,26 @@ final class AlmanacServiceSearchEngine
return 'PhabricatorAlmanacApplication';
}
public function buildSavedQueryFromRequest(AphrontRequest $request) {
$saved = new PhabricatorSavedQuery();
$this->saveQueryOrder($saved, $request);
return $saved;
public function newQuery() {
return new AlmanacServiceQuery();
}
public function buildQueryFromSavedQuery(PhabricatorSavedQuery $saved) {
$query = id(new AlmanacServiceQuery());
public function newResultObject() {
// NOTE: We need to attach a service type in order to generate custom
// field definitions.
return AlmanacService::initializeNewService()
->attachServiceType(new AlmanacCustomServiceType());
}
$this->setQueryOrder($query, $saved);
protected function buildQueryFromParameters(array $map) {
$query = $this->newQuery();
return $query;
}
public function buildSearchForm(
AphrontFormView $form,
PhabricatorSavedQuery $saved) {
$this->appendOrderFieldsToForm(
$form,
$saved,
new AlmanacServiceQuery());
protected function buildCustomSearchFields() {
return array();
}
protected function getURI($path) {
@ -62,12 +58,6 @@ final class AlmanacServiceSearchEngine
return parent::buildSavedQueryFromBuiltin($query_key);
}
protected function getRequiredHandlePHIDsForResultList(
array $services,
PhabricatorSavedQuery $query) {
return array();
}
protected function renderResultList(
array $services,
PhabricatorSavedQuery $query,

View file

@ -86,7 +86,7 @@ abstract class PhabricatorAphlictManagementWorkflow
exit(1);
}
protected final function setDebug($debug) {
final protected function setDebug($debug) {
$this->debug = $debug;
}

View file

@ -44,7 +44,9 @@ final class PhabricatorAuditCommentEditor extends PhabricatorEditor {
return array(
'diffusion-audit-'.$commit->getPHID(),
'Commit r'.$repository->getCallsign().$commit->getCommitIdentifier(),
pht(
'Commit %s',
'r'.$repository->getCallsign().$commit->getCommitIdentifier()),
);
}

View file

@ -8,6 +8,7 @@ final class PhabricatorAuditEditor
private $auditReasonMap = array();
private $affectedFiles;
private $rawPatch;
private $auditorPHIDs = array();
private $didExpandInlineState;
@ -342,6 +343,9 @@ final class PhabricatorAuditEditor
$object->writeImportStatusFlag($import_status_flag);
}
// Collect auditor PHIDs for building mail.
$this->auditorPHIDs = mpull($object->getAudits(), 'getAuditorPHID');
return $xactions;
}
@ -669,17 +673,11 @@ final class PhabricatorAuditEditor
$object);
}
// Reload the commit to pull commit data.
$commit = id(new DiffusionCommitQuery())
->setViewer($this->requireActor())
->withIDs(array($object->getID()))
->needCommitData(true)
->executeOne();
$data = $commit->getCommitData();
$data = $object->getCommitData();
$user_phids = array();
$author_phid = $commit->getAuthorPHID();
$author_phid = $object->getAuthorPHID();
if ($author_phid) {
$user_phids[$author_phid][] = pht('Author');
}
@ -689,10 +687,7 @@ final class PhabricatorAuditEditor
$user_phids[$committer_phid][] = pht('Committer');
}
// we loaded this in applyFinalEffects
$audit_requests = $object->getAudits();
$auditor_phids = mpull($audit_requests, 'getAuditorPHID');
foreach ($auditor_phids as $auditor_phid) {
foreach ($this->auditorPHIDs as $auditor_phid) {
$user_phids[$auditor_phid][] = pht('Auditor');
}
@ -894,6 +889,7 @@ final class PhabricatorAuditEditor
"H{$rule_id}"));
}
}
if ($audit_phids) {
$xactions[] = id(new PhabricatorAuditTransaction())
->setTransactionType(PhabricatorAuditActionConstants::ADD_AUDITORS)
@ -905,15 +901,6 @@ final class PhabricatorAuditEditor
'auditReasonMap', $this->auditReasonMap);
}
$cc_phids = $adapter->getAddCCMap();
$add_ccs = array('+' => array());
foreach ($cc_phids as $phid => $rule_ids) {
$add_ccs['+'][$phid] = $phid;
}
$xactions[] = id(new PhabricatorAuditTransaction())
->setTransactionType(PhabricatorTransactions::TYPE_SUBSCRIBERS)
->setNewValue($add_ccs);
HarbormasterBuildable::applyBuildPlans(
$object->getPHID(),
$object->getRepository()->getPHID(),
@ -983,4 +970,28 @@ final class PhabricatorAuditEditor
return $this->shouldPublishRepositoryActivity($object, $xactions);
}
protected function getCustomWorkerState() {
return array(
'rawPatch' => $this->rawPatch,
'affectedFiles' => $this->affectedFiles,
'auditorPHIDs' => $this->auditorPHIDs,
);
}
protected function loadCustomWorkerState(array $state) {
$this->rawPatch = idx($state, 'rawPatch');
$this->affectedFiles = idx($state, 'affectedFiles');
$this->auditorPHIDs = idx($state, 'auditorPHIDs');
return $this;
}
protected function willPublish(PhabricatorLiskDAO $object, array $xactions) {
return id(new DiffusionCommitQuery())
->setViewer($this->requireActor())
->withIDs(array($object->getID()))
->needAuditRequests(true)
->needCommitData(true)
->executeOne();
}
}

View file

@ -158,6 +158,21 @@ final class PhabricatorAuthSessionEngine extends Phobject {
$session_dict[substr($key, 2)] = $value;
}
}
$user = $user_table->loadFromArray($info);
switch ($session_type) {
case PhabricatorAuthSession::TYPE_WEB:
// Explicitly prevent bots and mailing lists from establishing web
// sessions. It's normally impossible to attach authentication to these
// accounts, and likewise impossible to generate sessions, but it's
// technically possible that a session could exist in the database. If
// one does somehow, refuse to load it.
if (!$user->canEstablishWebSessions()) {
return null;
}
break;
}
$session = id(new PhabricatorAuthSession())->loadFromArray($session_dict);
$ttl = PhabricatorAuthSession::getSessionTypeTTL($session_type);
@ -181,7 +196,6 @@ final class PhabricatorAuthSessionEngine extends Phobject {
unset($unguarded);
}
$user = $user_table->loadFromArray($info);
$user->attachSession($session);
return $user;
}

View file

@ -29,7 +29,7 @@ abstract class PhabricatorApplication implements PhabricatorPolicyInterface {
/* -( Application Information )-------------------------------------------- */
public abstract function getName();
abstract public function getName();
public function getShortDescription() {
return pht('%s Application', $this->getName());

View file

@ -114,10 +114,7 @@ abstract class PhabricatorController extends AphrontController {
$request->setUser($user);
}
$locale_code = $user->getTranslation();
if ($locale_code) {
PhabricatorEnv::setLocaleCode($locale_code);
}
PhabricatorEnv::setLocaleCode($user->getTranslation());
$preferences = $user->loadPreferences();
if (PhabricatorEnv::getEnvConfig('darkconsole.enabled')) {

View file

@ -1,12 +1,16 @@
<?php
/**
*
* @task request Request Cache
* @task immutable Immutable Cache
* @task setup Setup Cache
* @task compress Compression
*/
final class PhabricatorCaches {
private static $requestCache;
public static function getNamespace() {
return PhabricatorEnv::getEnvConfig('phabricator.cache-namespace');
}
@ -18,8 +22,39 @@ final class PhabricatorCaches {
->setCaches($caches);
}
/* -( Request Cache )------------------------------------------------------ */
/* -( Local Cache )-------------------------------------------------------- */
/**
* Get a request cache stack.
*
* This cache stack is destroyed after each logical request. In particular,
* it is destroyed periodically by the daemons, while `static` caches are
* not.
*
* @return PhutilKeyValueCacheStack Request cache stack.
*/
public static function getRequestCache() {
if (!self::$requestCache) {
self::$requestCache = new PhutilInRequestKeyValueCache();
}
return self::$requestCache;
}
/**
* Destroy the request cache.
*
* This is called at the beginning of each logical request.
*
* @return void
*/
public static function destroyRequestCache() {
self::$requestCache = null;
}
/* -( Immutable Cache )---------------------------------------------------- */
/**

View file

@ -0,0 +1,41 @@
<?php
final class PhabricatorCachesTestCase
extends PhabricatorTestCase {
public function testRequestCache() {
$cache = PhabricatorCaches::getRequestCache();
$test_key = 'unit.'.Filesystem::readRandomCharacters(8);
$default_value = pht('Default');
$new_value = pht('New Value');
$this->assertEqual(
$default_value,
$cache->getKey($test_key, $default_value));
// Set a key, verify it persists.
$cache = PhabricatorCaches::getRequestCache();
$cache->setKey($test_key, $new_value);
$this->assertEqual(
$new_value,
$cache->getKey($test_key, $default_value));
// Refetch the cache, verify it's really a cache.
$cache = PhabricatorCaches::getRequestCache();
$this->assertEqual(
$new_value,
$cache->getKey($test_key, $default_value));
// Destroy the cache.
PhabricatorCaches::destroyRequestCache();
// Now, the value should be missing again.
$cache = PhabricatorCaches::getRequestCache();
$this->assertEqual(
$default_value,
$cache->getKey($test_key, $default_value));
}
}

View file

@ -40,7 +40,8 @@ final class PhabricatorCalendarApplication extends PhabricatorApplication {
public function getRoutes() {
return array(
'/E(?P<id>[1-9]\d*)' => 'PhabricatorCalendarEventViewController',
'/E(?P<id>[1-9]\d*)(?:/(?P<sequence>\d+))?'
=> 'PhabricatorCalendarEventViewController',
'/calendar/' => array(
'(?:query/(?P<queryKey>[^/]+)/(?:(?P<year>\d+)/'.
'(?P<month>\d+)/)?(?:(?P<day>\d+)/)?)?'
@ -52,11 +53,11 @@ final class PhabricatorCalendarApplication extends PhabricatorApplication {
'event/' => array(
'create/'
=> 'PhabricatorCalendarEventEditController',
'edit/(?P<id>[1-9]\d*)/'
'edit/(?P<id>[1-9]\d*)/(?:(?P<sequence>\d+)/)?'
=> 'PhabricatorCalendarEventEditController',
'drag/(?P<id>[1-9]\d*)/'
=> 'PhabricatorCalendarEventDragController',
'cancel/(?P<id>[1-9]\d*)/'
'cancel/(?P<id>[1-9]\d*)/(?:(?P<sequence>\d+)/)?'
=> 'PhabricatorCalendarEventCancelController',
'(?P<action>join|decline|accept)/(?P<id>[1-9]\d*)/'
=> 'PhabricatorCalendarEventJoinController',

View file

@ -1,29 +0,0 @@
<?php
final class CalendarColors extends CalendarConstants {
const COLOR_RED = 'red';
const COLOR_ORANGE = 'orange';
const COLOR_YELLOW = 'yellow';
const COLOR_GREEN = 'green';
const COLOR_BLUE = 'blue';
const COLOR_SKY = 'sky';
const COLOR_INDIGO = 'indigo';
const COLOR_VIOLET = 'violet';
const COLOR_GREY = 'grey';
public static function getColors() {
return array(
self::COLOR_SKY,
self::COLOR_GREEN,
self::COLOR_VIOLET,
self::COLOR_ORANGE,
self::COLOR_BLUE,
self::COLOR_INDIGO,
self::COLOR_RED,
self::COLOR_YELLOW,
self::COLOR_GREY,
);
}
}

View file

@ -1,3 +0,0 @@
<?php
abstract class CalendarConstants {}

View file

@ -26,4 +26,47 @@ abstract class PhabricatorCalendarController extends PhabricatorController {
return $crumbs;
}
protected function getEventAtIndexForGhostPHID($viewer, $phid, $index) {
$result = id(new PhabricatorCalendarEventQuery())
->setViewer($viewer)
->withInstanceSequencePairs(
array(
array(
$phid,
$index,
),
))
->requireCapabilities(
array(
PhabricatorPolicyCapability::CAN_VIEW,
PhabricatorPolicyCapability::CAN_EDIT,
))
->executeOne();
return $result;
}
protected function createEventFromGhost($viewer, $event, $index) {
$invitees = $event->getInvitees();
$new_ghost = $event->generateNthGhost($index, $viewer);
$new_ghost->attachParentEvent($event);
$unguarded = AphrontWriteGuard::beginScopedUnguardedWrites();
$new_ghost
->setID(null)
->setPHID(null)
->removeViewerTimezone($viewer)
->save();
$ghost_invitees = array();
foreach ($invitees as $invitee) {
$ghost_invitee = clone $invitee;
$ghost_invitee
->setID(null)
->setEventPHID($new_ghost->getPHID())
->save();
}
unset($unguarded);
return $new_ghost;
}
}

View file

@ -12,8 +12,9 @@ final class PhabricatorCalendarEventCancelController
public function processRequest() {
$request = $this->getRequest();
$user = $request->getUser();
$sequence = $request->getURIData('sequence');
$status = id(new PhabricatorCalendarEventQuery())
$event = id(new PhabricatorCalendarEventQuery())
->setViewer($user)
->withIDs(array($this->id))
->requireCapabilities(
@ -23,15 +24,39 @@ final class PhabricatorCalendarEventCancelController
))
->executeOne();
if (!$status) {
if ($sequence) {
$parent_event = $event;
$event = $parent_event->generateNthGhost($sequence, $user);
$event->attachParentEvent($parent_event);
}
if (!$event) {
return new Aphront404Response();
}
$cancel_uri = '/E'.$status->getID();
if (!$sequence) {
$cancel_uri = '/E'.$event->getID();
} else {
$cancel_uri = '/E'.$event->getID().'/'.$sequence;
}
$is_cancelled = $event->getIsCancelled();
$is_parent_cancelled = $event->getIsParentCancelled();
$is_parent = $event->getIsRecurrenceParent();
$validation_exception = null;
$is_cancelled = $status->getIsCancelled();
if ($request->isFormPost()) {
if ($is_cancelled && $sequence) {
return id(new AphrontRedirectResponse())->setURI($cancel_uri);
} else if ($sequence) {
$event = $this->createEventFromGhost(
$user,
$event,
$sequence);
$event->applyViewerTimezone($user);
}
$xactions = array();
$xaction = id(new PhabricatorCalendarEventTransaction())
@ -46,7 +71,7 @@ final class PhabricatorCalendarEventCancelController
->setContinueOnMissingFields(true);
try {
$editor->applyTransactions($status, array($xaction));
$editor->applyTransactions($event, array($xaction));
return id(new AphrontRedirectResponse())->setURI($cancel_uri);
} catch (PhabricatorApplicationTransactionValidationException $ex) {
$validation_exception = $ex;
@ -54,15 +79,44 @@ final class PhabricatorCalendarEventCancelController
}
if ($is_cancelled) {
$title = pht('Reinstate Event');
$paragraph = pht('Reinstate this event?');
$cancel = pht('Don\'t Reinstate Event');
$submit = pht('Reinstate Event');
if ($sequence || $is_parent_cancelled) {
$title = pht('Cannot Reinstate Instance');
$paragraph = pht('Cannot reinstate an instance of a
cancelled recurring event.');
$cancel = pht('Cancel');
$submit = null;
} else if ($is_parent) {
$title = pht('Reinstate Recurrence');
$paragraph = pht('Reinstate the entire series
of recurring events?');
$cancel = pht('Don\'t Reinstate Recurrence');
$submit = pht('Reinstate Recurrence');
} else {
$title = pht('Reinstate Event');
$paragraph = pht('Reinstate this event?');
$cancel = pht('Don\'t Reinstate Event');
$submit = pht('Reinstate Event');
}
} else {
$title = pht('Cancel Event');
$paragraph = pht('You can always reinstate the event later.');
$cancel = pht('Don\'t Cancel Event');
$submit = pht('Cancel Event');
if ($sequence) {
$title = pht('Cancel Instance');
$paragraph = pht('Cancel just this instance
of a recurring event.');
$cancel = pht('Don\'t Cancel Instance');
$submit = pht('Cancel Instance');
} else if ($is_parent) {
$title = pht('Cancel Recurrence');
$paragraph = pht('Cancel the entire series
of recurring events?');
$cancel = pht('Don\'t Cancel Recurrence');
$submit = pht('Cancel Recurrence');
} else {
$title = pht('Cancel Event');
$paragraph = pht('You can always reinstate
the event later.');
$cancel = pht('Don\'t Cancel Event');
$submit = pht('Cancel Event');
}
}
return $this->newDialog()

View file

@ -17,13 +17,17 @@ final class PhabricatorCalendarEventEditController
$viewer = $request->getViewer();
$user_phid = $viewer->getPHID();
$error_name = true;
$error_recurrence_end_date = true;
$error_start_date = true;
$error_end_date = true;
$validation_exception = null;
$is_recurring_id = celerity_generate_unique_node_id();
$recurrence_end_date_id = celerity_generate_unique_node_id();
$frequency_id = celerity_generate_unique_node_id();
$all_day_id = celerity_generate_unique_node_id();
$start_date_id = celerity_generate_unique_node_id();
$end_date_id = null;
$end_date_id = celerity_generate_unique_node_id();
$next_workflow = $request->getStr('next');
$uri_query = $request->getStr('query');
@ -63,6 +67,8 @@ final class PhabricatorCalendarEventEditController
list($start_value, $end_value) = $this->getDefaultTimeValues($viewer);
}
$recurrence_end_date_value = clone $end_value;
$recurrence_end_date_value->setOptional(true);
$submit_label = pht('Create');
$page_title = pht('Create Event');
@ -70,27 +76,51 @@ final class PhabricatorCalendarEventEditController
$subscribers = array();
$invitees = array($user_phid);
$cancel_uri = $this->getApplicationURI();
$end_date_id = celerity_generate_unique_node_id();
} else {
$event = id(new PhabricatorCalendarEventQuery())
->setViewer($viewer)
->withIDs(array($this->id))
->requireCapabilities(
array(
PhabricatorPolicyCapability::CAN_VIEW,
PhabricatorPolicyCapability::CAN_EDIT,
))
->executeOne();
->setViewer($viewer)
->withIDs(array($this->id))
->requireCapabilities(
array(
PhabricatorPolicyCapability::CAN_VIEW,
PhabricatorPolicyCapability::CAN_EDIT,
))
->executeOne();
if (!$event) {
return new Aphront404Response();
}
if ($request->getURIData('sequence')) {
$index = $request->getURIData('sequence');
$result = $this->getEventAtIndexForGhostPHID(
$viewer,
$event->getPHID(),
$index);
if ($result) {
return id(new AphrontRedirectResponse())
->setURI('/calendar/event/edit/'.$result->getID().'/');
}
$event = $this->createEventFromGhost(
$viewer,
$event,
$index);
return id(new AphrontRedirectResponse())
->setURI('/calendar/event/edit/'.$event->getID().'/');
}
$end_value = AphrontFormDateControlValue::newFromEpoch(
$viewer,
$event->getDateTo());
$start_value = AphrontFormDateControlValue::newFromEpoch(
$viewer,
$event->getDateFrom());
$recurrence_end_date_value = id(clone $end_value)
->setOptional(true);
$submit_label = pht('Update');
$page_title = pht('Update Event');
@ -113,6 +143,9 @@ final class PhabricatorCalendarEventEditController
$name = $event->getName();
$description = $event->getDescription();
$is_all_day = $event->getIsAllDay();
$is_recurring = $event->getIsRecurring();
$is_parent = $event->getIsRecurrenceParent();
$frequency = idx($event->getRecurrenceFrequency(), 'rule');
$icon = $event->getIcon();
$current_policies = id(new PhabricatorPolicyQuery())
@ -130,10 +163,16 @@ final class PhabricatorCalendarEventEditController
$end_value = AphrontFormDateControlValue::newFromRequest(
$request,
'end');
$recurrence_end_date_value = AphrontFormDateControlValue::newFromRequest(
$request,
'recurrenceEndDate');
$recurrence_end_date_value->setOptional(true);
$description = $request->getStr('description');
$subscribers = $request->getArr('subscribers');
$edit_policy = $request->getStr('editPolicy');
$view_policy = $request->getStr('viewPolicy');
$is_recurring = $request->getStr('isRecurring') ? 1 : 0;
$frequency = $request->getStr('frequency');
$is_all_day = $request->getStr('isAllDay');
$icon = $request->getStr('icon');
@ -152,25 +191,47 @@ final class PhabricatorCalendarEventEditController
PhabricatorCalendarEventTransaction::TYPE_NAME)
->setNewValue($name);
$xactions[] = id(new PhabricatorCalendarEventTransaction())
->setTransactionType(
PhabricatorCalendarEventTransaction::TYPE_ALL_DAY)
->setNewValue($is_all_day);
if ($is_parent && $this->isCreate()) {
$xactions[] = id(new PhabricatorCalendarEventTransaction())
->setTransactionType(
PhabricatorCalendarEventTransaction::TYPE_RECURRING)
->setNewValue($is_recurring);
$xactions[] = id(new PhabricatorCalendarEventTransaction())
->setTransactionType(
PhabricatorCalendarEventTransaction::TYPE_ICON)
->setNewValue($icon);
$xactions[] = id(new PhabricatorCalendarEventTransaction())
->setTransactionType(
PhabricatorCalendarEventTransaction::TYPE_FREQUENCY)
->setNewValue(array('rule' => $frequency));
$xactions[] = id(new PhabricatorCalendarEventTransaction())
->setTransactionType(
PhabricatorCalendarEventTransaction::TYPE_START_DATE)
->setNewValue($start_value);
if (!$recurrence_end_date_value->isDisabled()) {
$xactions[] = id(new PhabricatorCalendarEventTransaction())
->setTransactionType(
PhabricatorCalendarEventTransaction::TYPE_RECURRENCE_END_DATE)
->setNewValue($recurrence_end_date_value);
}
}
if (($is_parent && $this->isCreate()) || !$is_parent) {
$xactions[] = id(new PhabricatorCalendarEventTransaction())
->setTransactionType(
PhabricatorCalendarEventTransaction::TYPE_ALL_DAY)
->setNewValue($is_all_day);
$xactions[] = id(new PhabricatorCalendarEventTransaction())
->setTransactionType(
PhabricatorCalendarEventTransaction::TYPE_ICON)
->setNewValue($icon);
$xactions[] = id(new PhabricatorCalendarEventTransaction())
->setTransactionType(
PhabricatorCalendarEventTransaction::TYPE_START_DATE)
->setNewValue($start_value);
$xactions[] = id(new PhabricatorCalendarEventTransaction())
->setTransactionType(
PhabricatorCalendarEventTransaction::TYPE_END_DATE)
->setNewValue($end_value);
}
$xactions[] = id(new PhabricatorCalendarEventTransaction())
->setTransactionType(
PhabricatorCalendarEventTransaction::TYPE_END_DATE)
->setNewValue($end_value);
$xactions[] = id(new PhabricatorCalendarEventTransaction())
->setTransactionType(
@ -227,17 +288,23 @@ final class PhabricatorCalendarEventEditController
PhabricatorCalendarEventTransaction::TYPE_START_DATE);
$error_end_date = $ex->getShortMessage(
PhabricatorCalendarEventTransaction::TYPE_END_DATE);
$error_recurrence_end_date = $ex->getShortMessage(
PhabricatorCalendarEventTransaction::TYPE_RECURRENCE_END_DATE);
$event->setViewPolicy($view_policy);
$event->setEditPolicy($edit_policy);
}
}
Javelin::initBehavior('event-all-day', array(
'allDayID' => $all_day_id,
'startDateID' => $start_date_id,
'endDateID' => $end_date_id,
));
$is_recurring_checkbox = null;
$recurrence_end_date_control = null;
$recurrence_frequency_select = null;
$all_day_checkbox = null;
$start_control = null;
$end_control = null;
$recurring_date_edit_label = null;
$name = id(new AphrontFormTextControl())
->setLabel(pht('Name'))
@ -245,32 +312,131 @@ final class PhabricatorCalendarEventEditController
->setValue($name)
->setError($error_name);
$all_day_checkbox = id(new AphrontFormCheckboxControl())
->addCheckbox(
'isAllDay',
1,
pht('All Day Event'),
$is_all_day,
$all_day_id);
if ($this->isCreate()) {
Javelin::initBehavior('recurring-edit', array(
'isRecurring' => $is_recurring_id,
'frequency' => $frequency_id,
'recurrenceEndDate' => $recurrence_end_date_id,
));
$start_control = id(new AphrontFormDateControl())
->setUser($viewer)
->setName('start')
->setLabel(pht('Start'))
->setError($error_start_date)
->setValue($start_value)
->setID($start_date_id)
->setIsTimeDisabled($is_all_day)
->setEndDateID($end_date_id);
$is_recurring_checkbox = id(new AphrontFormCheckboxControl())
->addCheckbox(
'isRecurring',
1,
pht('Recurring Event'),
$is_recurring,
$is_recurring_id);
$end_control = id(new AphrontFormDateControl())
->setUser($viewer)
->setName('end')
->setLabel(pht('End'))
->setError($error_end_date)
->setValue($end_value)
->setID($end_date_id)
->setIsTimeDisabled($is_all_day);
$recurrence_end_date_control = id(new AphrontFormDateControl())
->setUser($viewer)
->setName('recurrenceEndDate')
->setLabel(pht('Recurrence End Date'))
->setError($error_recurrence_end_date)
->setValue($recurrence_end_date_value)
->setID($recurrence_end_date_id)
->setIsTimeDisabled(true)
->setIsDisabled($recurrence_end_date_value->isDisabled())
->setAllowNull(true)
->isRequired(false);
$recurrence_frequency_select = id(new AphrontFormSelectControl())
->setName('frequency')
->setOptions(array(
'daily' => pht('Daily'),
'weekly' => pht('Weekly'),
'monthly' => pht('Monthly'),
'yearly' => pht('Yearly'),
))
->setValue($frequency)
->setLabel(pht('Recurring Event Frequency'))
->setID($frequency_id)
->setDisabled(!$is_recurring);
}
if ($this->isCreate() || (!$is_parent && !$this->isCreate())) {
Javelin::initBehavior('event-all-day', array(
'allDayID' => $all_day_id,
'startDateID' => $start_date_id,
'endDateID' => $end_date_id,
));
$all_day_checkbox = id(new AphrontFormCheckboxControl())
->addCheckbox(
'isAllDay',
1,
pht('All Day Event'),
$is_all_day,
$all_day_id);
$start_control = id(new AphrontFormDateControl())
->setUser($viewer)
->setName('start')
->setLabel(pht('Start'))
->setError($error_start_date)
->setValue($start_value)
->setID($start_date_id)
->setIsTimeDisabled($is_all_day)
->setEndDateID($end_date_id);
$end_control = id(new AphrontFormDateControl())
->setUser($viewer)
->setName('end')
->setLabel(pht('End'))
->setError($error_end_date)
->setValue($end_value)
->setID($end_date_id)
->setIsTimeDisabled($is_all_day);
} else if ($is_parent) {
$recurring_date_edit_label = id(new AphrontFormStaticControl())
->setUser($viewer)
->setValue(pht('Date and time of recurring event cannot be edited.'));
if (!$recurrence_end_date_value->isDisabled()) {
$disabled_recurrence_end_date_value =
$recurrence_end_date_value->getValueAsFormat('M d, Y');
$recurrence_end_date_control = id(new AphrontFormStaticControl())
->setUser($viewer)
->setLabel(pht('Recurrence End Date'))
->setValue($disabled_recurrence_end_date_value)
->setDisabled(true);
}
$recurrence_frequency_select = id(new AphrontFormSelectControl())
->setName('frequency')
->setOptions(array(
'daily' => pht('Daily'),
'weekly' => pht('Weekly'),
'monthly' => pht('Monthly'),
'yearly' => pht('Yearly'),
))
->setValue($frequency)
->setLabel(pht('Recurring Event Frequency'))
->setID($frequency_id)
->setDisabled(true);
$all_day_checkbox = id(new AphrontFormCheckboxControl())
->addCheckbox(
'isAllDay',
1,
pht('All Day Event'),
$is_all_day,
$all_day_id)
->setDisabled(true);
$start_disabled = $start_value->getValueAsFormat('M d, Y, g:i A');
$end_disabled = $end_value->getValueAsFormat('M d, Y, g:i A');
$start_control = id(new AphrontFormStaticControl())
->setUser($viewer)
->setLabel(pht('Start'))
->setValue($start_disabled)
->setDisabled(true);
$end_control = id(new AphrontFormStaticControl())
->setUser($viewer)
->setLabel(pht('End'))
->setValue($end_disabled);
}
$description = id(new AphrontFormTextAreaControl())
->setLabel(pht('Description'))
@ -322,7 +488,22 @@ final class PhabricatorCalendarEventEditController
->addHiddenInput('next', $next_workflow)
->addHiddenInput('query', $uri_query)
->setUser($viewer)
->appendChild($name)
->appendChild($name);
if ($recurring_date_edit_label) {
$form->appendControl($recurring_date_edit_label);
}
if ($is_recurring_checkbox) {
$form->appendChild($is_recurring_checkbox);
}
if ($recurrence_end_date_control) {
$form->appendChild($recurrence_end_date_control);
}
if ($recurrence_frequency_select) {
$form->appendControl($recurrence_frequency_select);
}
$form
->appendChild($all_day_checkbox)
->appendChild($start_control)
->appendChild($end_control)

View file

@ -17,6 +17,8 @@ final class PhabricatorCalendarEventViewController
$request = $this->getRequest();
$viewer = $request->getUser();
$sequence = $request->getURIData('sequence');
$event = id(new PhabricatorCalendarEventQuery())
->setViewer($viewer)
->withIDs(array($this->id))
@ -25,10 +27,38 @@ final class PhabricatorCalendarEventViewController
return new Aphront404Response();
}
$title = 'E'.$event->getID();
$page_title = $title.' '.$event->getName();
$crumbs = $this->buildApplicationCrumbs();
$crumbs->addTextCrumb($title, '/E'.$event->getID());
if ($sequence) {
$result = $this->getEventAtIndexForGhostPHID(
$viewer,
$event->getPHID(),
$sequence);
if ($result) {
$parent_event = $event;
$event = $result;
$event->attachParentEvent($parent_event);
return id(new AphrontRedirectResponse())
->setURI('/E'.$result->getID());
} else if ($sequence && $event->getIsRecurring()) {
$parent_event = $event;
$event = $event->generateNthGhost($sequence, $viewer);
$event->attachParentEvent($parent_event);
} else if ($sequence) {
return new Aphront404Response();
}
$title = $event->getMonogram().' ('.$sequence.')';
$page_title = $title.' '.$event->getName();
$crumbs = $this->buildApplicationCrumbs();
$crumbs->addTextCrumb($title, '/'.$event->getMonogram().'/'.$sequence);
} else {
$title = 'E'.$event->getID();
$page_title = $title.' '.$event->getName();
$crumbs = $this->buildApplicationCrumbs();
$crumbs->addTextCrumb($title, '/E'.$event->getID());
}
$timeline = $this->buildTransactionTimeline(
$event,
@ -127,13 +157,30 @@ final class PhabricatorCalendarEventViewController
$event,
PhabricatorPolicyCapability::CAN_EDIT);
$actions->addAction(
id(new PhabricatorActionView())
->setName(pht('Edit Event'))
->setIcon('fa-pencil')
->setHref($this->getApplicationURI("event/edit/{$id}/"))
->setDisabled(!$can_edit)
->setWorkflow(!$can_edit));
$edit_label = false;
$edit_uri = false;
if ($event->getIsGhostEvent()) {
$index = $event->getSequenceIndex();
$edit_label = pht('Edit This Instance');
$edit_uri = "event/edit/{$id}/{$index}/";
} else if ($event->getIsRecurrenceException()) {
$edit_label = pht('Edit This Instance');
$edit_uri = "event/edit/{$id}/";
} else {
$edit_label = pht('Edit');
$edit_uri = "event/edit/{$id}/";
}
if ($edit_label && $edit_uri) {
$actions->addAction(
id(new PhabricatorActionView())
->setName($edit_label)
->setIcon('fa-pencil')
->setHref($this->getApplicationURI($edit_uri))
->setDisabled(!$can_edit)
->setWorkflow(!$can_edit));
}
if ($is_attending) {
$actions->addAction(
@ -151,21 +198,46 @@ final class PhabricatorCalendarEventViewController
->setWorkflow(true));
}
$cancel_uri = $this->getApplicationURI("event/cancel/{$id}/");
if ($event->getIsGhostEvent()) {
$index = $event->getSequenceIndex();
$can_reinstate = $event->getIsParentCancelled();
$cancel_label = pht('Cancel This Instance');
$reinstate_label = pht('Reinstate This Instance');
$cancel_disabled = (!$can_edit || $can_reinstate);
$cancel_uri = $this->getApplicationURI("event/cancel/{$id}/{$index}/");
} else if ($event->getIsRecurrenceException()) {
$can_reinstate = $event->getIsParentCancelled();
$cancel_label = pht('Cancel This Instance');
$reinstate_label = pht('Reinstate This Instance');
$cancel_disabled = (!$can_edit || $can_reinstate);
} else if ($event->getIsRecurrenceParent()) {
$cancel_label = pht('Cancel Recurrence');
$reinstate_label = pht('Reinstate Recurrence');
$cancel_disabled = !$can_edit;
} else {
$cancel_label = pht('Cancel Event');
$reinstate_label = pht('Reinstate Event');
$cancel_disabled = !$can_edit;
}
if ($is_cancelled) {
$actions->addAction(
id(new PhabricatorActionView())
->setName(pht('Reinstate Event'))
->setName($reinstate_label)
->setIcon('fa-plus')
->setHref($this->getApplicationURI("event/cancel/{$id}/"))
->setDisabled(!$can_edit)
->setHref($cancel_uri)
->setDisabled($cancel_disabled)
->setWorkflow(true));
} else {
$actions->addAction(
id(new PhabricatorActionView())
->setName(pht('Cancel Event'))
->setName($cancel_label)
->setIcon('fa-times')
->setHref($this->getApplicationURI("event/cancel/{$id}/"))
->setDisabled(!$can_edit)
->setHref($cancel_uri)
->setDisabled($cancel_disabled)
->setWorkflow(true));
}
@ -205,6 +277,24 @@ final class PhabricatorCalendarEventViewController
phabricator_datetime($event->getDateTo(), $viewer));
}
if ($event->getIsRecurring()) {
$properties->addProperty(
pht('Recurs'),
ucwords(idx($event->getRecurrenceFrequency(), 'rule')));
if ($event->getRecurrenceEndDate()) {
$properties->addProperty(
pht('Recurrence Ends'),
phabricator_datetime($event->getRecurrenceEndDate(), $viewer));
}
if ($event->getInstanceOfEventPHID()) {
$properties->addProperty(
pht('Recurrence of Event'),
$viewer->renderHandle($event->getInstanceOfEventPHID()));
}
}
$properties->addProperty(
pht('Host'),
$viewer->renderHandle($event->getUserPHID()));

View file

@ -23,6 +23,12 @@ final class PhabricatorCalendarEventEditor
$types[] = PhabricatorCalendarEventTransaction::TYPE_ALL_DAY;
$types[] = PhabricatorCalendarEventTransaction::TYPE_ICON;
$types[] = PhabricatorCalendarEventTransaction::TYPE_RECURRING;
$types[] = PhabricatorCalendarEventTransaction::TYPE_FREQUENCY;
$types[] = PhabricatorCalendarEventTransaction::TYPE_RECURRENCE_END_DATE;
$types[] = PhabricatorCalendarEventTransaction::TYPE_INSTANCE_OF_EVENT;
$types[] = PhabricatorCalendarEventTransaction::TYPE_SEQUENCE_INDEX;
$types[] = PhabricatorTransactions::TYPE_COMMENT;
$types[] = PhabricatorTransactions::TYPE_VIEW_POLICY;
$types[] = PhabricatorTransactions::TYPE_EDIT_POLICY;
@ -34,6 +40,16 @@ final class PhabricatorCalendarEventEditor
PhabricatorLiskDAO $object,
PhabricatorApplicationTransaction $xaction) {
switch ($xaction->getTransactionType()) {
case PhabricatorCalendarEventTransaction::TYPE_RECURRING:
return $object->getIsRecurring();
case PhabricatorCalendarEventTransaction::TYPE_FREQUENCY:
return $object->getRecurrenceFrequency();
case PhabricatorCalendarEventTransaction::TYPE_RECURRENCE_END_DATE:
return $object->getRecurrenceEndDate();
case PhabricatorCalendarEventTransaction::TYPE_INSTANCE_OF_EVENT:
return $object->getInstanceOfEventPHID();
case PhabricatorCalendarEventTransaction::TYPE_SEQUENCE_INDEX:
return $object->getSequenceIndex();
case PhabricatorCalendarEventTransaction::TYPE_NAME:
return $object->getName();
case PhabricatorCalendarEventTransaction::TYPE_START_DATE:
@ -72,6 +88,10 @@ final class PhabricatorCalendarEventEditor
PhabricatorLiskDAO $object,
PhabricatorApplicationTransaction $xaction) {
switch ($xaction->getTransactionType()) {
case PhabricatorCalendarEventTransaction::TYPE_RECURRING:
case PhabricatorCalendarEventTransaction::TYPE_FREQUENCY:
case PhabricatorCalendarEventTransaction::TYPE_INSTANCE_OF_EVENT:
case PhabricatorCalendarEventTransaction::TYPE_SEQUENCE_INDEX:
case PhabricatorCalendarEventTransaction::TYPE_NAME:
case PhabricatorCalendarEventTransaction::TYPE_DESCRIPTION:
case PhabricatorCalendarEventTransaction::TYPE_CANCEL:
@ -80,6 +100,7 @@ final class PhabricatorCalendarEventEditor
return $xaction->getNewValue();
case PhabricatorCalendarEventTransaction::TYPE_ALL_DAY:
return (int)$xaction->getNewValue();
case PhabricatorCalendarEventTransaction::TYPE_RECURRENCE_END_DATE:
case PhabricatorCalendarEventTransaction::TYPE_START_DATE:
case PhabricatorCalendarEventTransaction::TYPE_END_DATE:
return $xaction->getNewValue()->getEpoch();
@ -93,6 +114,14 @@ final class PhabricatorCalendarEventEditor
PhabricatorApplicationTransaction $xaction) {
switch ($xaction->getTransactionType()) {
case PhabricatorCalendarEventTransaction::TYPE_RECURRING:
return $object->setIsRecurring($xaction->getNewValue());
case PhabricatorCalendarEventTransaction::TYPE_FREQUENCY:
return $object->setRecurrenceFrequency($xaction->getNewValue());
case PhabricatorCalendarEventTransaction::TYPE_INSTANCE_OF_EVENT:
return $object->setInstanceOfEventPHID($xaction->getNewValue());
case PhabricatorCalendarEventTransaction::TYPE_SEQUENCE_INDEX:
return $object->setSequenceIndex($xaction->getNewValue());
case PhabricatorCalendarEventTransaction::TYPE_NAME:
$object->setName($xaction->getNewValue());
return;
@ -102,6 +131,9 @@ final class PhabricatorCalendarEventEditor
case PhabricatorCalendarEventTransaction::TYPE_END_DATE:
$object->setDateTo($xaction->getNewValue());
return;
case PhabricatorCalendarEventTransaction::TYPE_RECURRENCE_END_DATE:
$object->setRecurrenceEndDate($xaction->getNewValue());
return;
case PhabricatorCalendarEventTransaction::TYPE_DESCRIPTION:
$object->setDescription($xaction->getNewValue());
return;
@ -126,6 +158,11 @@ final class PhabricatorCalendarEventEditor
PhabricatorApplicationTransaction $xaction) {
switch ($xaction->getTransactionType()) {
case PhabricatorCalendarEventTransaction::TYPE_RECURRING:
case PhabricatorCalendarEventTransaction::TYPE_FREQUENCY:
case PhabricatorCalendarEventTransaction::TYPE_RECURRENCE_END_DATE:
case PhabricatorCalendarEventTransaction::TYPE_INSTANCE_OF_EVENT:
case PhabricatorCalendarEventTransaction::TYPE_SEQUENCE_INDEX:
case PhabricatorCalendarEventTransaction::TYPE_NAME:
case PhabricatorCalendarEventTransaction::TYPE_START_DATE:
case PhabricatorCalendarEventTransaction::TYPE_END_DATE:
@ -181,6 +218,11 @@ final class PhabricatorCalendarEventEditor
switch ($xaction->getTransactionType()) {
case PhabricatorCalendarEventTransaction::TYPE_ICON:
break;
case PhabricatorCalendarEventTransaction::TYPE_RECURRING:
case PhabricatorCalendarEventTransaction::TYPE_FREQUENCY:
case PhabricatorCalendarEventTransaction::TYPE_RECURRENCE_END_DATE:
case PhabricatorCalendarEventTransaction::TYPE_INSTANCE_OF_EVENT:
case PhabricatorCalendarEventTransaction::TYPE_SEQUENCE_INDEX:
case PhabricatorCalendarEventTransaction::TYPE_START_DATE:
case PhabricatorCalendarEventTransaction::TYPE_END_DATE:
case PhabricatorCalendarEventTransaction::TYPE_CANCEL:
@ -223,10 +265,20 @@ final class PhabricatorCalendarEventEditor
protected function validateAllTransactions(
PhabricatorLiskDAO $object,
array $xactions) {
$start_date_xaction = PhabricatorCalendarEventTransaction::TYPE_START_DATE;
$end_date_xaction = PhabricatorCalendarEventTransaction::TYPE_END_DATE;
$start_date_xaction =
PhabricatorCalendarEventTransaction::TYPE_START_DATE;
$end_date_xaction =
PhabricatorCalendarEventTransaction::TYPE_END_DATE;
$is_recurrence_xaction =
PhabricatorCalendarEventTransaction::TYPE_RECURRING;
$recurrence_end_xaction =
PhabricatorCalendarEventTransaction::TYPE_RECURRENCE_END_DATE;
$start_date = $object->getDateFrom();
$end_date = $object->getDateTo();
$recurrence_end = $object->getRecurrenceEndDate();
$is_recurring = $object->getIsRecurring();
$errors = array();
foreach ($xactions as $xaction) {
@ -234,6 +286,10 @@ final class PhabricatorCalendarEventEditor
$start_date = $xaction->getNewValue()->getEpoch();
} else if ($xaction->getTransactionType() == $end_date_xaction) {
$end_date = $xaction->getNewValue()->getEpoch();
} else if ($xaction->getTransactionType() == $recurrence_end_xaction) {
$recurrence_end = $xaction->getNewValue();
} else if ($xaction->getTransactionType() == $is_recurrence_xaction) {
$is_recurring = $xaction->getNewValue();
}
}
if ($start_date > $end_date) {
@ -245,6 +301,16 @@ final class PhabricatorCalendarEventEditor
null);
}
if ($recurrence_end && !$is_recurring) {
$type =
PhabricatorCalendarEventTransaction::TYPE_RECURRENCE_END_DATE;
$errors[] = new PhabricatorApplicationTransactionValidationError(
$type,
pht('Invalid'),
pht('Event must be recurring to have a recurrence end date.').
null);
}
return $errors;
}
@ -272,6 +338,7 @@ final class PhabricatorCalendarEventEditor
$errors[] = $error;
}
break;
case PhabricatorCalendarEventTransaction::TYPE_RECURRENCE_END_DATE:
case PhabricatorCalendarEventTransaction::TYPE_START_DATE:
case PhabricatorCalendarEventTransaction::TYPE_END_DATE:
foreach ($xactions as $xaction) {
@ -303,9 +370,7 @@ final class PhabricatorCalendarEventEditor
protected function shouldSendMail(
PhabricatorLiskDAO $object,
array $xactions) {
$xactions = mfilter($xactions, 'shouldHide', true);
return $xactions;
return true;
}
protected function getMailSubjectPrefix() {

View file

@ -10,6 +10,15 @@ final class PhabricatorCalendarEventQuery
private $inviteePHIDs;
private $creatorPHIDs;
private $isCancelled;
private $eventsWithNoParent;
private $instanceSequencePairs;
private $generateGhosts = false;
public function setGenerateGhosts($generate_ghosts) {
$this->generateGhosts = $generate_ghosts;
return $this;
}
public function withIDs(array $ids) {
$this->ids = $ids;
@ -42,6 +51,16 @@ final class PhabricatorCalendarEventQuery
return $this;
}
public function withEventsWithNoParent($events_with_no_parent) {
$this->eventsWithNoParent = $events_with_no_parent;
return $this;
}
public function withInstanceSequencePairs(array $pairs) {
$this->instanceSequencePairs = $pairs;
return $this;
}
protected function getDefaultOrderVector() {
return array('start', 'id');
}
@ -69,6 +88,7 @@ final class PhabricatorCalendarEventQuery
protected function loadPage() {
$table = new PhabricatorCalendarEvent();
$conn_r = $table->establishConnection('r');
$viewer = $this->getViewer();
$data = queryfx_all(
$conn_r,
@ -86,6 +106,131 @@ final class PhabricatorCalendarEventQuery
$event->applyViewerTimezone($this->getViewer());
}
if (!$this->generateGhosts) {
return $events;
}
$enforced_end = null;
foreach ($events as $key => $event) {
$sequence_start = 0;
$sequence_end = null;
$duration = $event->getDateTo() - $event->getDateFrom();
$end = null;
$instance_of = $event->getInstanceOfEventPHID();
if ($instance_of == null && $this->isCancelled !== null) {
if ($event->getIsCancelled() != $this->isCancelled) {
unset($events[$key]);
continue;
}
}
if ($event->getIsRecurring() && $instance_of == null) {
$frequency = $event->getFrequencyUnit();
$modify_key = '+1 '.$frequency;
if ($this->rangeBegin && $this->rangeBegin > $event->getDateFrom()) {
$max_date = $this->rangeBegin - $duration;
$date = $event->getDateFrom();
$datetime = PhabricatorTime::getDateTimeFromEpoch($date, $viewer);
while ($date < $max_date) {
// TODO: optimize this to not loop through all off-screen events
$sequence_start++;
$datetime = PhabricatorTime::getDateTimeFromEpoch($date, $viewer);
$date = $datetime->modify($modify_key)->format('U');
}
$start = $this->rangeBegin;
} else {
$start = $event->getDateFrom() - $duration;
}
$date = $start;
$datetime = PhabricatorTime::getDateTimeFromEpoch($date, $viewer);
if (($this->rangeEnd && $event->getRecurrenceEndDate()) &&
$this->rangeEnd < $event->getRecurrenceEndDate()) {
$end = $this->rangeEnd;
} else if ($event->getRecurrenceEndDate()) {
$end = $event->getRecurrenceEndDate();
} else if ($this->rangeEnd) {
$end = $this->rangeEnd;
} else if ($enforced_end) {
if ($end) {
$end = min($end, $enforced_end);
} else {
$end = $enforced_end;
}
}
if ($end) {
$sequence_end = $sequence_start;
while ($date < $end) {
$sequence_end++;
$datetime->modify($modify_key);
$date = $datetime->format('U');
if ($sequence_end > $this->getRawResultLimit() + $sequence_start) {
break;
}
}
} else {
$sequence_end = $this->getRawResultLimit() + $sequence_start;
}
$sequence_start = max(1, $sequence_start);
for ($index = $sequence_start; $index < $sequence_end; $index++) {
$events[] = $event->generateNthGhost($index, $viewer);
}
if (count($events) >= $this->getRawResultLimit()) {
$events = msort($events, 'getDateFrom');
$events = array_slice($events, 0, $this->getRawResultLimit(), true);
$enforced_end = last($events)->getDateFrom();
}
}
}
$map = array();
$instance_sequence_pairs = array();
foreach ($events as $key => $event) {
if ($event->getIsGhostEvent()) {
$index = $event->getSequenceIndex();
$instance_sequence_pairs[] = array($event->getPHID(), $index);
$map[$event->getPHID()][$index] = $key;
}
}
if (count($instance_sequence_pairs) > 0) {
$sub_query = id(new PhabricatorCalendarEventQuery())
->setViewer($viewer)
->setParentQuery($this)
->withInstanceSequencePairs($instance_sequence_pairs)
->execute();
foreach ($sub_query as $edited_ghost) {
$indexes = idx($map, $edited_ghost->getInstanceOfEventPHID());
$key = idx($indexes, $edited_ghost->getSequenceIndex());
$events[$key] = $edited_ghost;
}
$id_map = array();
foreach ($events as $key => $event) {
if ($event->getIsGhostEvent()) {
continue;
}
if (isset($id_map[$event->getID()])) {
unset($events[$key]);
} else {
$id_map[$event->getID()] = true;
}
}
}
return $events;
}
@ -122,7 +267,7 @@ final class PhabricatorCalendarEventQuery
if ($this->rangeBegin) {
$where[] = qsprintf(
$conn_r,
'event.dateTo >= %d',
'event.dateTo >= %d OR event.isRecurring = 1',
$this->rangeBegin);
}
@ -154,6 +299,28 @@ final class PhabricatorCalendarEventQuery
(int)$this->isCancelled);
}
if ($this->eventsWithNoParent == true) {
$where[] = qsprintf(
$conn_r,
'event.instanceOfEventPHID IS NULL');
}
if ($this->instanceSequencePairs !== null) {
$sql = array();
foreach ($this->instanceSequencePairs as $pair) {
$sql[] = qsprintf(
$conn_r,
'(event.instanceOfEventPHID = %s AND event.sequenceIndex = %d)',
$pair[0],
$pair[1]);
}
$where[] = qsprintf(
$conn_r,
'%Q',
implode(' OR ', $sql));
}
$where[] = $this->buildPagingClause($conn_r);
return $this->formatWhereClause($where);
@ -182,6 +349,9 @@ final class PhabricatorCalendarEventQuery
protected function willFilterPage(array $events) {
$range_start = $this->rangeBegin;
$range_end = $this->rangeEnd;
$instance_of_event_phids = array();
$recurring_events = array();
$viewer = $this->getViewer();
foreach ($events as $key => $event) {
$event_start = $event->getDateFrom();
@ -199,17 +369,56 @@ final class PhabricatorCalendarEventQuery
foreach ($events as $event) {
$phids[] = $event->getPHID();
$instance_of = $event->getInstanceOfEventPHID();
if ($instance_of) {
$instance_of_event_phids[] = $instance_of;
}
}
$invitees = id(new PhabricatorCalendarEventInviteeQuery())
->setViewer($this->getViewer())
->withEventPHIDs($phids)
->execute();
$invitees = mgroup($invitees, 'getEventPHID');
if (count($instance_of_event_phids) > 0) {
$recurring_events = id(new PhabricatorCalendarEventQuery())
->setViewer($viewer)
->withPHIDs($instance_of_event_phids)
->withEventsWithNoParent(true)
->execute();
foreach ($events as $event) {
$recurring_events = mpull($recurring_events, null, 'getPHID');
}
if ($events) {
$invitees = id(new PhabricatorCalendarEventInviteeQuery())
->setViewer($viewer)
->withEventPHIDs($phids)
->execute();
$invitees = mgroup($invitees, 'getEventPHID');
} else {
$invitees = array();
}
foreach ($events as $key => $event) {
$event_invitees = idx($invitees, $event->getPHID(), array());
$event->attachInvitees($event_invitees);
$instance_of = $event->getInstanceOfEventPHID();
if (!$instance_of) {
continue;
}
$parent = idx($recurring_events, $instance_of);
// should never get here
if (!$parent) {
unset($events[$key]);
continue;
}
$event->attachParentEvent($parent);
if ($this->isCancelled !== null) {
if ($event->getIsCancelled() != $this->isCancelled) {
unset($events[$key]);
continue;
}
}
}
$events = msort($events, 'getDateFrom');

View file

@ -50,7 +50,8 @@ final class PhabricatorCalendarEventSearchEngine
}
public function buildQueryFromSavedQuery(PhabricatorSavedQuery $saved) {
$query = id(new PhabricatorCalendarEventQuery());
$query = id(new PhabricatorCalendarEventQuery())
->setGenerateGhosts(true);
$viewer = $this->requireViewer();
$timezone = new DateTimeZone($viewer->getTimezoneIdentifier());
@ -132,7 +133,8 @@ final class PhabricatorCalendarEventSearchEngine
$query->withCreatorPHIDs($creator_phids);
}
$is_cancelled = $saved->getParameter('isCancelled');
$is_cancelled = $saved->getParameter('isCancelled', 'active');
switch ($is_cancelled) {
case 'active':
$query->withIsCancelled(false);
@ -305,14 +307,13 @@ final class PhabricatorCalendarEventSearchEngine
$viewer = $this->requireViewer();
$list = new PHUIObjectItemListView();
foreach ($events as $event) {
$href = '/E'.$event->getID();
$from = phabricator_datetime($event->getDateFrom(), $viewer);
$to = phabricator_datetime($event->getDateTo(), $viewer);
$creator_handle = $handles[$event->getUserPHID()];
$item = id(new PHUIObjectItemView())
->setHeader($event->getName())
->setHref($href)
->setHref($event->getURI())
->addByline(pht('Creator: %s', $creator_handle->renderLink()))
->addAttribute(pht('From %s to %s', $from, $to))
->addAttribute(id(new PhutilUTF8StringTruncator())
@ -371,7 +372,7 @@ final class PhabricatorCalendarEventSearchEngine
$event->setUserPHID($status->getUserPHID());
$event->setDescription(pht('%s (%s)', $name_text, $status_text));
$event->setName($status_text);
$event->setEventID($status->getID());
$event->setURI($status->getURI());
$event->setViewerIsInvited($viewer_is_invited);
$month_view->addEvent($event);
}
@ -423,7 +424,7 @@ final class PhabricatorCalendarEventSearchEngine
$event->setViewerIsInvited($viewer_is_invited);
$event->setName($status->getName());
$event->setURI('/'.$status->getMonogram());
$event->setURI($status->getURI());
$day_view->addEvent($event);
}
@ -461,7 +462,11 @@ final class PhabricatorCalendarEventSearchEngine
}
public function getPageSize(PhabricatorSavedQuery $saved) {
return $saved->getParameter('limit', 1000);
if ($this->isMonthView($saved) || $this->isDayView($saved)) {
return $saved->getParameter('limit', 1000);
} else {
return $saved->getParameter('limit', 100);
}
}
private function getDateFrom(PhabricatorSavedQuery $saved) {

View file

@ -18,7 +18,7 @@ final class PhabricatorCalendarEventSearchIndexer
$doc->setDocumentModified($event->getDateModified());
$doc->addField(
PhabricatorSearchField::FIELD_BODY,
PhabricatorSearchDocumentFieldType::FIELD_BODY,
$event->getDescription());
$doc->addRelationship(

View file

@ -20,11 +20,20 @@ final class PhabricatorCalendarEvent extends PhabricatorCalendarDAO
protected $icon;
protected $mailKey;
protected $isRecurring = 0;
protected $recurrenceFrequency = array();
protected $recurrenceEndDate;
private $isGhostEvent = false;
protected $instanceOfEventPHID;
protected $sequenceIndex;
protected $viewPolicy;
protected $editPolicy;
const DEFAULT_ICON = 'fa-calendar';
private $parentEvent = self::ATTACHABLE;
private $invitees = self::ATTACHABLE;
private $appliedViewer;
@ -36,8 +45,13 @@ final class PhabricatorCalendarEvent extends PhabricatorCalendarDAO
->withClasses(array('PhabricatorCalendarApplication'))
->executeOne();
$view_policy = null;
$is_recurring = 0;
if ($mode == 'public') {
$view_policy = PhabricatorPolicies::getMostOpenPolicy();
} else if ($mode == 'recurring') {
$is_recurring = true;
} else {
$view_policy = $actor->getPHID();
}
@ -46,6 +60,7 @@ final class PhabricatorCalendarEvent extends PhabricatorCalendarDAO
->setUserPHID($actor->getPHID())
->setIsCancelled(0)
->setIsAllDay(0)
->setIsRecurring($is_recurring)
->setIcon(self::DEFAULT_ICON)
->setViewPolicy($view_policy)
->setEditPolicy($actor->getPHID())
@ -180,11 +195,22 @@ final class PhabricatorCalendarEvent extends PhabricatorCalendarDAO
'isAllDay' => 'bool',
'icon' => 'text32',
'mailKey' => 'bytes20',
'isRecurring' => 'bool',
'recurrenceEndDate' => 'epoch?',
'instanceOfEventPHID' => 'phid?',
'sequenceIndex' => 'uint32?',
),
self::CONFIG_KEY_SCHEMA => array(
'userPHID_dateFrom' => array(
'columns' => array('userPHID', 'dateTo'),
),
'key_instance' => array(
'columns' => array('instanceOfEventPHID', 'sequenceIndex'),
'unique' => true,
),
),
self::CONFIG_SERIALIZATION => array(
'recurrenceFrequency' => self::SERIALIZATION_JSON,
),
) + parent::getConfiguration();
}
@ -238,6 +264,115 @@ final class PhabricatorCalendarEvent extends PhabricatorCalendarDAO
return true;
}
public function getIsGhostEvent() {
return $this->isGhostEvent;
}
public function setIsGhostEvent($is_ghost_event) {
$this->isGhostEvent = $is_ghost_event;
return $this;
}
public function generateNthGhost(
$sequence_index,
PhabricatorUser $actor) {
$frequency = $this->getFrequencyUnit();
$modify_key = '+'.$sequence_index.' '.$frequency;
$instance_of = ($this->getPHID()) ?
$this->getPHID() : $this->instanceOfEventPHID;
$date = $this->dateFrom;
$date_time = PhabricatorTime::getDateTimeFromEpoch($date, $actor);
$date_time->modify($modify_key);
$date = $date_time->format('U');
$duration = $this->dateTo - $this->dateFrom;
$edit_policy = PhabricatorPolicies::POLICY_NOONE;
$ghost_event = id(clone $this)
->setIsGhostEvent(true)
->setDateFrom($date)
->setDateTo($date + $duration)
->setIsRecurring(true)
->setRecurrenceFrequency($this->recurrenceFrequency)
->setInstanceOfEventPHID($instance_of)
->setSequenceIndex($sequence_index)
->setEditPolicy($edit_policy);
return $ghost_event;
}
public function getFrequencyUnit() {
$frequency = idx($this->recurrenceFrequency, 'rule');
switch ($frequency) {
case 'daily':
return 'day';
case 'weekly':
return 'week';
case 'monthly':
return 'month';
case 'yearly':
return 'yearly';
default:
return 'day';
}
}
public function getURI() {
$uri = '/'.$this->getMonogram();
if ($this->isGhostEvent) {
$uri = $uri.'/'.$this->sequenceIndex;
}
return $uri;
}
public function getParentEvent() {
return $this->assertAttached($this->parentEvent);
}
public function attachParentEvent($event) {
$this->parentEvent = $event;
return $this;
}
public function getIsCancelled() {
$instance_of = $this->instanceOfEventPHID;
if ($instance_of != null && $this->getIsParentCancelled()) {
return true;
}
return $this->isCancelled;
}
public function getIsRecurrenceParent() {
if ($this->isRecurring && !$this->instanceOfEventPHID) {
return true;
}
return false;
}
public function getIsRecurrenceException() {
if ($this->instanceOfEventPHID && !$this->isGhostEvent) {
return true;
}
return false;
}
public function getIsParentCancelled() {
if ($this->instanceOfEventPHID == null) {
return false;
}
$recurring_event = $this->getParentEvent();
if ($recurring_event->getIsCancelled()) {
return true;
}
return false;
}
/* -( Markup Interface )--------------------------------------------------- */
@ -328,7 +463,8 @@ final class PhabricatorCalendarEvent extends PhabricatorCalendarDAO
public function describeAutomaticCapability($capability) {
return pht('The owner of an event can always view and edit it,
and invitees can always view it.');
and invitees can always view it, except if the event is an
instance of a recurring event.');
}
/* -( PhabricatorApplicationTransactionInterface )------------------------- */

View file

@ -12,6 +12,13 @@ final class PhabricatorCalendarEventTransaction
const TYPE_ICON = 'calendar.icon';
const TYPE_INVITE = 'calendar.invite';
const TYPE_RECURRING = 'calendar.recurring';
const TYPE_FREQUENCY = 'calendar.frequency';
const TYPE_RECURRENCE_END_DATE = 'calendar.recurrenceenddate';
const TYPE_INSTANCE_OF_EVENT = 'calendar.instanceofevent';
const TYPE_SEQUENCE_INDEX = 'calendar.sequenceindex';
const MAILTAG_RESCHEDULE = 'calendar-reschedule';
const MAILTAG_CONTENT = 'calendar-content';
const MAILTAG_OTHER = 'calendar-other';
@ -38,6 +45,11 @@ final class PhabricatorCalendarEventTransaction
case self::TYPE_DESCRIPTION:
case self::TYPE_CANCEL:
case self::TYPE_ALL_DAY:
case self::TYPE_RECURRING:
case self::TYPE_FREQUENCY:
case self::TYPE_RECURRENCE_END_DATE:
case self::TYPE_INSTANCE_OF_EVENT:
case self::TYPE_SEQUENCE_INDEX:
$phids[] = $this->getObjectPHID();
break;
case self::TYPE_INVITE:
@ -60,6 +72,11 @@ final class PhabricatorCalendarEventTransaction
case self::TYPE_CANCEL:
case self::TYPE_ALL_DAY:
case self::TYPE_INVITE:
case self::TYPE_RECURRING:
case self::TYPE_FREQUENCY:
case self::TYPE_RECURRENCE_END_DATE:
case self::TYPE_INSTANCE_OF_EVENT:
case self::TYPE_SEQUENCE_INDEX:
return ($old === null);
}
return parent::shouldHide();
@ -75,6 +92,11 @@ final class PhabricatorCalendarEventTransaction
case self::TYPE_DESCRIPTION:
case self::TYPE_ALL_DAY:
case self::TYPE_CANCEL:
case self::TYPE_RECURRING:
case self::TYPE_FREQUENCY:
case self::TYPE_RECURRENCE_END_DATE:
case self::TYPE_INSTANCE_OF_EVENT:
case self::TYPE_SEQUENCE_INDEX:
return 'fa-pencil';
break;
case self::TYPE_INVITE:
@ -231,6 +253,12 @@ final class PhabricatorCalendarEventTransaction
}
}
return $text;
case self::TYPE_RECURRING:
case self::TYPE_FREQUENCY:
case self::TYPE_RECURRENCE_END_DATE:
case self::TYPE_INSTANCE_OF_EVENT:
case self::TYPE_SEQUENCE_INDEX:
return pht('Recurring event has been updated');
}
return parent::getTitle();
}
@ -365,8 +393,6 @@ final class PhabricatorCalendarEventTransaction
$added = array();
$uninvited = array();
// $event = $this->renderHandleLink($object_phid);
foreach ($new as $phid => $status) {
if ($status == PhabricatorCalendarEventInvitee::STATUS_INVITED
|| $status == PhabricatorCalendarEventInvitee::STATUS_ATTENDING) {
@ -411,6 +437,12 @@ final class PhabricatorCalendarEventTransaction
}
}
return $text;
case self::TYPE_RECURRING:
case self::TYPE_FREQUENCY:
case self::TYPE_RECURRENCE_END_DATE:
case self::TYPE_INSTANCE_OF_EVENT:
case self::TYPE_SEQUENCE_INDEX:
return pht('Recurring event has been updated');
}
return parent::getTitleForFeed();

View file

@ -165,7 +165,7 @@ abstract class CelerityResourceController extends PhabricatorController {
}
private function getCacheKey($path) {
return 'celerity:'.$path;
return 'celerity:'.PhabricatorHash::digestToLength($path, 64);
}
}

View file

@ -60,10 +60,6 @@ final class PhabricatorConduitAPIController
// CSRF validation or are using a non-web authentication mechanism.
$allow_unguarded_writes = true;
if (isset($metadata['actAsUser'])) {
$this->actAsUser($api_request, $metadata['actAsUser']);
}
if ($auth_error === null) {
$conduit_user = $api_request->getUser();
if ($conduit_user && $conduit_user->getPHID()) {
@ -163,44 +159,6 @@ final class PhabricatorConduitAPIController
}
}
/**
* Change the api request user to the user that we want to act as.
* Only admins can use actAsUser
*
* @param ConduitAPIRequest Request being executed.
* @param string The username of the user we want to act as
*/
private function actAsUser(
ConduitAPIRequest $api_request,
$user_name) {
$config_key = 'security.allow-conduit-act-as-user';
if (!PhabricatorEnv::getEnvConfig($config_key)) {
throw new Exception(pht('%s is disabled.', $config_key));
}
if (!$api_request->getUser()->getIsAdmin()) {
throw new Exception(
pht(
'Only administrators can use %s.',
__FUNCTION__));
}
$user = id(new PhabricatorUser())->loadOneWhere(
'userName = %s',
$user_name);
if (!$user) {
throw new Exception(
pht(
"The %s username '%s' is not a valid user.",
__FUNCTION__,
$user_name));
}
$api_request->setUser($user);
}
/**
* Authenticate the client making the request to a Phabricator user account.
*
@ -517,10 +475,10 @@ final class PhabricatorConduitAPIController
ConduitAPIRequest $request,
PhabricatorUser $user) {
if (!$user->isUserActivated()) {
if (!$user->canEstablishAPISessions()) {
return array(
'ERR-USER-DISABLED',
pht('User account is not activated.'),
'ERR-INVALID-AUTH',
pht('User account is not permitted to use the API.'),
);
}

View file

@ -90,7 +90,7 @@ abstract class ConduitAPIMethod
return $this->execute($request);
}
public abstract function getAPIMethodName();
abstract public function getAPIMethodName();
/**
* Return a key which sorts methods by application name, then method status,

View file

@ -20,6 +20,10 @@ final class PhabricatorConduitTokensSettingsPanel
}
public function isEnabled() {
if ($this->getUser()->getIsMailingList()) {
return false;
}
return true;
}

View file

@ -271,6 +271,9 @@ final class PhabricatorExtraConfigSetupCheck extends PhabricatorSetupCheck {
'metamta.maniphest.public-create-email' => $public_mail_reason,
'metamta.maniphest.default-public-author' => $public_mail_reason,
'metamta.paste.public-create-email' => $public_mail_reason,
'security.allow-conduit-act-as-user' => pht(
'Impersonating users over the API is no longer supported.'),
);
return $ancient_config;

View file

@ -54,6 +54,8 @@ alincoln", "To: usgrant", "To: htaft"). The major advantages and disadvantages
of each approach are:
- One mail to everyone:
- This violates policy controls. The body of the mail is generated without
respect for object policies.
- Recipients can see To/Cc at a glance.
- If you use mailing lists, you won't get duplicate mail if you're
a normal recipient and also Cc'd on a mailing list.
@ -65,6 +67,7 @@ of each approach are:
- Not supported with a private reply-to address.
- Mails are sent in the server default translation.
- One mail to each user:
- Policy controls work correctly and are enforced per-user.
- Recipients need to look in the mail body to see To/Cc.
- If you use mailing lists, recipients may sometimes get duplicate
mail.
@ -74,8 +77,6 @@ of each approach are:
- Required if private reply-to addresses are configured.
- Mails are sent in the language of user preference.
In the code, splitting one outbound email into one-per-recipient is sometimes
referred to as "multiplexing".
EODOC
));
@ -222,6 +223,7 @@ EODOC
'metamta.one-mail-per-recipient',
'bool',
true)
->setLocked(true)
->setBoolOptions(
array(
pht('Send Mail To Each Recipient'),

View file

@ -278,22 +278,6 @@ final class PhabricatorSecurityConfigOptions
'unsecured content over plain HTTP. It is very difficult to '.
'undo this change once users\' browsers have accepted the '.
'setting.')),
$this->newOption('security.allow-conduit-act-as-user', 'bool', false)
->setBoolOptions(
array(
pht('Allow'),
pht('Disallow'),
))
->setLocked(true)
->setSummary(
pht('Allow administrators to use the Conduit API as other users.'))
->setDescription(
pht(
'DEPRECATED - if you enable this, you are allowing '.
'administrators to act as any user via the Conduit API. '.
'Enabling this is not advised as it introduces a huge policy '.
'violation and has been obsoleted in functionality.')),
);
}

View file

@ -61,7 +61,7 @@ final class ConpherenceTransactionRenderer {
// between days. some setup required!
$previous_transaction = null;
$date_marker_transaction = id(new ConpherenceTransaction())
->setTransactionType(ConpherenceTransactionType::TYPE_DATE_MARKER)
->setTransactionType(ConpherenceTransaction::TYPE_DATE_MARKER)
->makeEphemeral();
$date_marker_transaction_view = id(new ConpherenceTransactionView())
->setUser($user)
@ -74,7 +74,8 @@ final class ConpherenceTransactionRenderer {
->setUser($user)
->setConpherenceThread($conpherence)
->setHandles($handles)
->setMarkupEngine($engine);
->setMarkupEngine($engine)
->setFullDisplay($full_display);
foreach ($transactions as $transaction) {
if ($previous_transaction) {
@ -96,21 +97,6 @@ final class ConpherenceTransactionRenderer {
}
$transaction_view = id(clone $transaction_view_template)
->setConpherenceTransaction($transaction);
if ($full_display) {
$transaction_view
->setAnchor(
$transaction->getID(),
phabricator_time($transaction->getDateCreated(), $user));
$transaction_view->setContentSource($transaction->getContentSource());
$transaction_view->setShowImages(true);
} else {
$transaction_view
->setEpoch(
$transaction->getDateCreated(),
'/'.$conpherence->getMonogram().'#'.$transaction->getID())
->setTimeOnly(true);
$transaction_view->setShowImages(false);
}
$rendered_transactions[] = $transaction_view->render();
$previous_transaction = $transaction;

View file

@ -157,11 +157,11 @@ final class ConpherenceRoomTestCase extends ConpherenceTestCase {
$xactions = array();
$xactions[] = id(new ConpherenceTransaction())
->setTransactionType(ConpherenceTransactionType::TYPE_PARTICIPANTS)
->setTransactionType(ConpherenceTransaction::TYPE_PARTICIPANTS)
->setNewValue(array('+' => $participant_phids));
$xactions[] = id(new ConpherenceTransaction())
->setTransactionType(ConpherenceTransactionType::TYPE_TITLE)
->setNewValue('Test');
->setTransactionType(ConpherenceTransaction::TYPE_TITLE)
->setNewValue(pht('Test'));
id(new ConpherenceEditor())
->setActor($creator)

View file

@ -8,7 +8,7 @@ abstract class ConpherenceTestCase extends PhabricatorTestCase {
array $participant_phids) {
$xactions = array(id(new ConpherenceTransaction())
->setTransactionType(ConpherenceTransactionType::TYPE_PARTICIPANTS)
->setTransactionType(ConpherenceTransaction::TYPE_PARTICIPANTS)
->setNewValue(array('+' => $participant_phids)),
);
$editor = id(new ConpherenceEditor())
@ -24,7 +24,7 @@ abstract class ConpherenceTestCase extends PhabricatorTestCase {
array $participant_phids) {
$xactions = array(id(new ConpherenceTransaction())
->setTransactionType(ConpherenceTransactionType::TYPE_PARTICIPANTS)
->setTransactionType(ConpherenceTransaction::TYPE_PARTICIPANTS)
->setNewValue(array('-' => $participant_phids)),
);
$editor = id(new ConpherenceEditor())

View file

@ -160,8 +160,8 @@ final class ConpherenceThreadTestCase extends ConpherenceTestCase {
list($errors, $conpherence) = ConpherenceEditor::createThread(
$creator,
$participant_phids,
'Test',
'Test',
pht('Test'),
pht('Test'),
PhabricatorContentSource::newConsoleSource());
return $conpherence;
}

View file

@ -71,7 +71,7 @@ final class ConpherenceUpdateThreadConduitAPIMethod
if ($add_participant_phids) {
$xactions[] = id(new ConpherenceTransaction())
->setTransactionType(
ConpherenceTransactionType::TYPE_PARTICIPANTS)
ConpherenceTransaction::TYPE_PARTICIPANTS)
->setNewValue(array('+' => $add_participant_phids));
}
if ($remove_participant_phid) {
@ -80,12 +80,12 @@ final class ConpherenceUpdateThreadConduitAPIMethod
}
$xactions[] = id(new ConpherenceTransaction())
->setTransactionType(
ConpherenceTransactionType::TYPE_PARTICIPANTS)
ConpherenceTransaction::TYPE_PARTICIPANTS)
->setNewValue(array('-' => array($remove_participant_phid)));
}
if ($title) {
$xactions[] = id(new ConpherenceTransaction())
->setTransactionType(ConpherenceTransactionType::TYPE_TITLE)
->setTransactionType(ConpherenceTransaction::TYPE_TITLE)
->setNewValue($title);
}
if ($message) {

View file

@ -1,12 +0,0 @@
<?php
final class ConpherenceTransactionType extends ConpherenceConstants {
const TYPE_FILES = 'files';
const TYPE_TITLE = 'title';
const TYPE_PARTICIPANTS = 'participants';
const TYPE_DATE_MARKER = 'date-marker';
const TYPE_PICTURE = 'picture';
const TYPE_PICTURE_CROP = 'picture-crop';
}

View file

@ -14,10 +14,10 @@ final class ConpherenceNewRoomController extends ConpherenceController {
$xactions = array();
$xactions[] = id(new ConpherenceTransaction())
->setTransactionType(ConpherenceTransactionType::TYPE_PARTICIPANTS)
->setTransactionType(ConpherenceTransaction::TYPE_PARTICIPANTS)
->setNewValue(array('+' => array($user->getPHID())));
$xactions[] = id(new ConpherenceTransaction())
->setTransactionType(ConpherenceTransactionType::TYPE_TITLE)
->setTransactionType(ConpherenceTransaction::TYPE_TITLE)
->setNewValue($request->getStr('title'));
$xactions[] = id(new ConpherenceTransaction())
->setTransactionType(PhabricatorTransactions::TYPE_VIEW_POLICY)
@ -41,7 +41,7 @@ final class ConpherenceNewRoomController extends ConpherenceController {
} catch (PhabricatorApplicationTransactionValidationException $ex) {
$validation_exception = $ex;
$e_title = $ex->getShortMessage(ConpherenceTransactionType::TYPE_TITLE);
$e_title = $ex->getShortMessage(ConpherenceTransaction::TYPE_TITLE);
$conpherence->setViewPolicy($request->getStr('viewPolicy'));
$conpherence->setEditPolicy($request->getStr('editPolicy'));

View file

@ -67,7 +67,7 @@ final class ConpherenceUpdateController
case ConpherenceUpdateActions::JOIN_ROOM:
$xactions[] = id(new ConpherenceTransaction())
->setTransactionType(
ConpherenceTransactionType::TYPE_PARTICIPANTS)
ConpherenceTransaction::TYPE_PARTICIPANTS)
->setNewValue(array('+' => array($user->getPHID())));
$delete_draft = true;
$message = $request->getStr('text');
@ -101,7 +101,7 @@ final class ConpherenceUpdateController
if (!empty($person_phids)) {
$xactions[] = id(new ConpherenceTransaction())
->setTransactionType(
ConpherenceTransactionType::TYPE_PARTICIPANTS)
ConpherenceTransaction::TYPE_PARTICIPANTS)
->setNewValue(array('+' => $person_phids));
}
break;
@ -114,7 +114,7 @@ final class ConpherenceUpdateController
if ($person_phid && $person_phid == $user->getPHID()) {
$xactions[] = id(new ConpherenceTransaction())
->setTransactionType(
ConpherenceTransactionType::TYPE_PARTICIPANTS)
ConpherenceTransaction::TYPE_PARTICIPANTS)
->setNewValue(array('-' => array($person_phid)));
$response_mode = 'go-home';
}
@ -144,7 +144,7 @@ final class ConpherenceUpdateController
->withIDs(array($file_id))
->executeOne();
$xactions[] = id(new ConpherenceTransaction())
->setTransactionType(ConpherenceTransactionType::TYPE_PICTURE)
->setTransactionType(ConpherenceTransaction::TYPE_PICTURE)
->setNewValue($orig_file);
$okay = $orig_file->isTransformableImage();
if ($okay) {
@ -157,7 +157,7 @@ final class ConpherenceUpdateController
ConpherenceImageData::CROP_HEIGHT);
$xactions[] = id(new ConpherenceTransaction())
->setTransactionType(
ConpherenceTransactionType::TYPE_PICTURE_CROP)
ConpherenceTransaction::TYPE_PICTURE_CROP)
->setNewValue($crop_file->getPHID());
}
$response_mode = 'redirect';
@ -181,12 +181,12 @@ final class ConpherenceUpdateController
$xactions[] = id(new ConpherenceTransaction())
->setTransactionType(
ConpherenceTransactionType::TYPE_PICTURE_CROP)
ConpherenceTransaction::TYPE_PICTURE_CROP)
->setNewValue($image_phid);
}
$title = $request->getStr('title');
$xactions[] = id(new ConpherenceTransaction())
->setTransactionType(ConpherenceTransactionType::TYPE_TITLE)
->setTransactionType(ConpherenceTransaction::TYPE_TITLE)
->setNewValue($title);
if ($conpherence->getIsRoom()) {
$xactions[] = id(new ConpherenceTransaction())

View file

@ -47,16 +47,16 @@ final class ConpherenceEditor extends PhabricatorApplicationTransactionEditor {
if (!$errors) {
$xactions = array();
$xactions[] = id(new ConpherenceTransaction())
->setTransactionType(ConpherenceTransactionType::TYPE_PARTICIPANTS)
->setTransactionType(ConpherenceTransaction::TYPE_PARTICIPANTS)
->setNewValue(array('+' => $participant_phids));
if ($files) {
$xactions[] = id(new ConpherenceTransaction())
->setTransactionType(ConpherenceTransactionType::TYPE_FILES)
->setTransactionType(ConpherenceTransaction::TYPE_FILES)
->setNewValue(array('+' => mpull($files, 'getPHID')));
}
if ($title) {
$xactions[] = id(new ConpherenceTransaction())
->setTransactionType(ConpherenceTransactionType::TYPE_TITLE)
->setTransactionType(ConpherenceTransaction::TYPE_TITLE)
->setNewValue($title);
}
@ -100,7 +100,7 @@ final class ConpherenceEditor extends PhabricatorApplicationTransactionEditor {
$xactions = array();
if ($files) {
$xactions[] = id(new ConpherenceTransaction())
->setTransactionType(ConpherenceTransactionType::TYPE_FILES)
->setTransactionType(ConpherenceTransaction::TYPE_FILES)
->setNewValue(array('+' => mpull($files, 'getPHID')));
}
$xactions[] = id(new ConpherenceTransaction())
@ -117,11 +117,11 @@ final class ConpherenceEditor extends PhabricatorApplicationTransactionEditor {
$types[] = PhabricatorTransactions::TYPE_COMMENT;
$types[] = ConpherenceTransactionType::TYPE_TITLE;
$types[] = ConpherenceTransactionType::TYPE_PARTICIPANTS;
$types[] = ConpherenceTransactionType::TYPE_FILES;
$types[] = ConpherenceTransactionType::TYPE_PICTURE;
$types[] = ConpherenceTransactionType::TYPE_PICTURE_CROP;
$types[] = ConpherenceTransaction::TYPE_TITLE;
$types[] = ConpherenceTransaction::TYPE_PARTICIPANTS;
$types[] = ConpherenceTransaction::TYPE_FILES;
$types[] = ConpherenceTransaction::TYPE_PICTURE;
$types[] = ConpherenceTransaction::TYPE_PICTURE_CROP;
$types[] = PhabricatorTransactions::TYPE_VIEW_POLICY;
$types[] = PhabricatorTransactions::TYPE_EDIT_POLICY;
$types[] = PhabricatorTransactions::TYPE_JOIN_POLICY;
@ -134,18 +134,18 @@ final class ConpherenceEditor extends PhabricatorApplicationTransactionEditor {
PhabricatorApplicationTransaction $xaction) {
switch ($xaction->getTransactionType()) {
case ConpherenceTransactionType::TYPE_TITLE:
case ConpherenceTransaction::TYPE_TITLE:
return $object->getTitle();
case ConpherenceTransactionType::TYPE_PICTURE:
case ConpherenceTransaction::TYPE_PICTURE:
return $object->getImagePHID(ConpherenceImageData::SIZE_ORIG);
case ConpherenceTransactionType::TYPE_PICTURE_CROP:
case ConpherenceTransaction::TYPE_PICTURE_CROP:
return $object->getImagePHID(ConpherenceImageData::SIZE_CROP);
case ConpherenceTransactionType::TYPE_PARTICIPANTS:
case ConpherenceTransaction::TYPE_PARTICIPANTS:
if ($this->getIsNewObject()) {
return array();
}
return $object->getParticipantPHIDs();
case ConpherenceTransactionType::TYPE_FILES:
case ConpherenceTransaction::TYPE_FILES:
return $object->getFilePHIDs();
}
}
@ -155,14 +155,14 @@ final class ConpherenceEditor extends PhabricatorApplicationTransactionEditor {
PhabricatorApplicationTransaction $xaction) {
switch ($xaction->getTransactionType()) {
case ConpherenceTransactionType::TYPE_TITLE:
case ConpherenceTransactionType::TYPE_PICTURE_CROP:
case ConpherenceTransaction::TYPE_TITLE:
case ConpherenceTransaction::TYPE_PICTURE_CROP:
return $xaction->getNewValue();
case ConpherenceTransactionType::TYPE_PICTURE:
case ConpherenceTransaction::TYPE_PICTURE:
$file = $xaction->getNewValue();
return $file->getPHID();
case ConpherenceTransactionType::TYPE_PARTICIPANTS:
case ConpherenceTransactionType::TYPE_FILES:
case ConpherenceTransaction::TYPE_PARTICIPANTS:
case ConpherenceTransaction::TYPE_FILES:
return $this->getPHIDTransactionNewValue($xaction);
}
}
@ -207,7 +207,7 @@ final class ConpherenceEditor extends PhabricatorApplicationTransactionEditor {
foreach ($xactions as $xaction) {
switch ($xaction->getTransactionType()) {
case ConpherenceTransactionType::TYPE_PARTICIPANTS:
case ConpherenceTransaction::TYPE_PARTICIPANTS:
// Since this is a new ConpherenceThread, we have to create the
// participation data asap to pass policy checks. For existing
// ConpherenceThreads, the existing participation is correct
@ -247,20 +247,20 @@ final class ConpherenceEditor extends PhabricatorApplicationTransactionEditor {
$make_author_recent_participant = true;
switch ($xaction->getTransactionType()) {
case ConpherenceTransactionType::TYPE_TITLE:
case ConpherenceTransaction::TYPE_TITLE:
$object->setTitle($xaction->getNewValue());
break;
case ConpherenceTransactionType::TYPE_PICTURE:
case ConpherenceTransaction::TYPE_PICTURE:
$object->setImagePHID(
$xaction->getNewValue(),
ConpherenceImageData::SIZE_ORIG);
break;
case ConpherenceTransactionType::TYPE_PICTURE_CROP:
case ConpherenceTransaction::TYPE_PICTURE_CROP:
$object->setImagePHID(
$xaction->getNewValue(),
ConpherenceImageData::SIZE_CROP);
break;
case ConpherenceTransactionType::TYPE_PARTICIPANTS:
case ConpherenceTransaction::TYPE_PARTICIPANTS:
if (!$this->getIsNewObject()) {
$old_map = array_fuse($xaction->getOldValue());
$new_map = array_fuse($xaction->getNewValue());
@ -322,7 +322,7 @@ final class ConpherenceEditor extends PhabricatorApplicationTransactionEditor {
PhabricatorApplicationTransaction $xaction) {
switch ($xaction->getTransactionType()) {
case ConpherenceTransactionType::TYPE_FILES:
case ConpherenceTransaction::TYPE_FILES:
$editor = new PhabricatorEdgeEditor();
$edge_type = PhabricatorObjectHasFileEdgeType::EDGECONST;
$old = array_fill_keys($xaction->getOldValue(), true);
@ -343,7 +343,7 @@ final class ConpherenceEditor extends PhabricatorApplicationTransactionEditor {
}
$editor->save();
break;
case ConpherenceTransactionType::TYPE_PARTICIPANTS:
case ConpherenceTransaction::TYPE_PARTICIPANTS:
if ($this->getIsNewObject()) {
continue;
}
@ -443,7 +443,7 @@ final class ConpherenceEditor extends PhabricatorApplicationTransactionEditor {
parent::requireCapabilities($object, $xaction);
switch ($xaction->getTransactionType()) {
case ConpherenceTransactionType::TYPE_PARTICIPANTS:
case ConpherenceTransaction::TYPE_PARTICIPANTS:
$old_map = array_fuse($xaction->getOldValue());
$new_map = array_fuse($xaction->getNewValue());
@ -473,13 +473,13 @@ final class ConpherenceEditor extends PhabricatorApplicationTransactionEditor {
break;
// This is similar to PhabricatorTransactions::TYPE_COMMENT so
// use CAN_VIEW
case ConpherenceTransactionType::TYPE_FILES:
case ConpherenceTransaction::TYPE_FILES:
PhabricatorPolicyFilter::requireCapability(
$this->requireActor(),
$object,
PhabricatorPolicyCapability::CAN_VIEW);
break;
case ConpherenceTransactionType::TYPE_TITLE:
case ConpherenceTransaction::TYPE_TITLE:
PhabricatorPolicyFilter::requireCapability(
$this->requireActor(),
$object,
@ -494,10 +494,10 @@ final class ConpherenceEditor extends PhabricatorApplicationTransactionEditor {
$type = $u->getTransactionType();
switch ($type) {
case ConpherenceTransactionType::TYPE_TITLE:
case ConpherenceTransaction::TYPE_TITLE:
return $v;
case ConpherenceTransactionType::TYPE_FILES:
case ConpherenceTransactionType::TYPE_PARTICIPANTS:
case ConpherenceTransaction::TYPE_FILES:
case ConpherenceTransaction::TYPE_PARTICIPANTS:
return $this->mergePHIDOrEdgeTransactions($u, $v);
}
@ -576,6 +576,21 @@ final class ConpherenceEditor extends PhabricatorApplicationTransactionEditor {
return $body;
}
protected function addEmailPreferenceSectionToMailBody(
PhabricatorMetaMTAMailBody $body,
PhabricatorLiskDAO $object,
array $xactions) {
$href = PhabricatorEnv::getProductionURI(
'/'.$object->getMonogram().'?settings');
if ($object->getIsRoom()) {
$label = pht('EMAIL PREFERENCES FOR THIS ROOM');
} else {
$label = pht('EMAIL PREFERENCES FOR THIS MESSAGE');
}
$body->addLinkSection($label, $href);
}
protected function getMailSubjectPrefix() {
return PhabricatorEnv::getEnvConfig('metamta.conpherence.subject-prefix');
}
@ -611,9 +626,9 @@ final class ConpherenceEditor extends PhabricatorApplicationTransactionEditor {
PhabricatorApplicationTransaction $xaction) {
switch ($xaction->getTransactionType()) {
case ConpherenceTransactionType::TYPE_PICTURE:
case ConpherenceTransaction::TYPE_PICTURE:
return array($xaction->getNewValue()->getPHID());
case ConpherenceTransactionType::TYPE_PICTURE_CROP:
case ConpherenceTransaction::TYPE_PICTURE_CROP:
return array($xaction->getNewValue());
}
@ -628,7 +643,7 @@ final class ConpherenceEditor extends PhabricatorApplicationTransactionEditor {
$errors = parent::validateTransaction($object, $type, $xactions);
switch ($type) {
case ConpherenceTransactionType::TYPE_TITLE:
case ConpherenceTransaction::TYPE_TITLE:
if (!$object->getIsRoom()) {
continue;
}
@ -652,7 +667,7 @@ final class ConpherenceEditor extends PhabricatorApplicationTransactionEditor {
$errors[] = $error;
}
break;
case ConpherenceTransactionType::TYPE_PICTURE:
case ConpherenceTransaction::TYPE_PICTURE:
foreach ($xactions as $xaction) {
$file = $xaction->getNewValue();
if (!$file->isTransformableImage()) {
@ -667,7 +682,7 @@ final class ConpherenceEditor extends PhabricatorApplicationTransactionEditor {
}
}
break;
case ConpherenceTransactionType::TYPE_PARTICIPANTS:
case ConpherenceTransaction::TYPE_PARTICIPANTS:
foreach ($xactions as $xaction) {
$new_phids = $this->getPHIDTransactionNewValue($xaction, array());
$old_phids = nonempty($object->getParticipantPHIDs(), array());

View file

@ -21,9 +21,8 @@ final class ConpherenceReplyHandler extends PhabricatorMailReplyHandler {
}
}
public function getPrivateReplyHandlerEmailAddress(
PhabricatorObjectHandle $handle) {
return $this->getDefaultPrivateReplyHandlerEmailAddress($handle, 'Z');
public function getPrivateReplyHandlerEmailAddress(PhabricatorUser $user) {
return $this->getDefaultPrivateReplyHandlerEmailAddress($user, 'Z');
}
public function getPublicReplyHandlerEmailAddress() {
@ -66,7 +65,7 @@ final class ConpherenceReplyHandler extends PhabricatorMailReplyHandler {
$xactions = array();
if ($this->getMailAddedParticipantPHIDs()) {
$xactions[] = id(new ConpherenceTransaction())
->setTransactionType(ConpherenceTransactionType::TYPE_PARTICIPANTS)
->setTransactionType(ConpherenceTransaction::TYPE_PARTICIPANTS)
->setNewValue(array('+' => $this->getMailAddedParticipantPHIDs()));
}

View file

@ -19,9 +19,7 @@ final class PhabricatorConpherenceThreadPHIDType extends PhabricatorPHIDType {
protected function buildQueryForObjects(
PhabricatorObjectQuery $query,
array $phids) {
return id(new ConpherenceThreadQuery())
->needParticipantCache(true)
->withPHIDs($phids);
}
@ -33,7 +31,7 @@ final class PhabricatorConpherenceThreadPHIDType extends PhabricatorPHIDType {
foreach ($handles as $phid => $handle) {
$thread = $objects[$phid];
$title = $thread->getDisplayTitle($query->getViewer());
$title = $thread->getStaticTitle();
$monogram = $thread->getMonogram();
$handle->setName($title);

View file

@ -227,15 +227,13 @@ final class ConpherenceThreadSearchEngine
continue;
}
$history_href = '/'.$monogram.'#'.$xaction->getID();
$view = id(new ConpherenceTransactionView())
->setUser($viewer)
->setHandles($handles)
->setMarkupEngine($engines[$conpherence_phid])
->setConpherenceThread($conpherence)
->setConpherenceTransaction($xaction)
->setEpoch($xaction->getDateCreated(), $history_href)
->setFullDisplay(false)
->addClass('conpherence-fulltext-result');
if ($message['match']) {

View file

@ -199,6 +199,23 @@ final class ConpherenceThread extends ConpherenceDAO
return PhabricatorUser::getDefaultProfileImageURI();
}
/**
* Get a thread title which doesn't require handles to be attached.
*
* This is a less rich title than @{method:getDisplayTitle}, but does not
* require handles to be attached. We use it to build thread handles without
* risking cycles or recursion while querying.
*
* @return string Lower quality human-readable title.
*/
public function getStaticTitle() {
$title = $this->getTitle();
if (strlen($title)) {
return $title;
}
return pht('Private Correspondence');
}
/**
* Get the thread's display title for a user.

View file

@ -2,6 +2,13 @@
final class ConpherenceTransaction extends PhabricatorApplicationTransaction {
const TYPE_FILES = 'files';
const TYPE_TITLE = 'title';
const TYPE_PARTICIPANTS = 'participants';
const TYPE_DATE_MARKER = 'date-marker';
const TYPE_PICTURE = 'picture';
const TYPE_PICTURE_CROP = 'picture-crop';
public function getApplicationName() {
return 'conpherence';
}
@ -16,7 +23,7 @@ final class ConpherenceTransaction extends PhabricatorApplicationTransaction {
public function getNoEffectDescription() {
switch ($this->getTransactionType()) {
case ConpherenceTransactionType::TYPE_PARTICIPANTS:
case self::TYPE_PARTICIPANTS:
return pht(
'You can not add a participant who has already been added.');
break;
@ -29,15 +36,15 @@ final class ConpherenceTransaction extends PhabricatorApplicationTransaction {
$old = $this->getOldValue();
switch ($this->getTransactionType()) {
case ConpherenceTransactionType::TYPE_PARTICIPANTS:
case self::TYPE_PARTICIPANTS:
return ($old === null);
case ConpherenceTransactionType::TYPE_TITLE:
case ConpherenceTransactionType::TYPE_PICTURE:
case ConpherenceTransactionType::TYPE_DATE_MARKER:
case self::TYPE_TITLE:
case self::TYPE_PICTURE:
case self::TYPE_DATE_MARKER:
return false;
case ConpherenceTransactionType::TYPE_FILES:
case self::TYPE_FILES:
return true;
case ConpherenceTransactionType::TYPE_PICTURE_CROP:
case self::TYPE_PICTURE_CROP:
return true;
}
@ -51,18 +58,18 @@ final class ConpherenceTransaction extends PhabricatorApplicationTransaction {
$new = $this->getNewValue();
switch ($this->getTransactionType()) {
case ConpherenceTransactionType::TYPE_TITLE:
case self::TYPE_TITLE:
case PhabricatorTransactions::TYPE_VIEW_POLICY:
case PhabricatorTransactions::TYPE_EDIT_POLICY:
case PhabricatorTransactions::TYPE_JOIN_POLICY:
case ConpherenceTransactionType::TYPE_PICTURE:
case self::TYPE_PICTURE:
if ($this->getObject()->getIsRoom()) {
return $this->getRoomTitle();
} else {
return $this->getThreadTitle();
}
break;
case ConpherenceTransactionType::TYPE_FILES:
case self::TYPE_FILES:
$add = array_diff($new, $old);
$rem = array_diff($old, $new);
@ -85,7 +92,7 @@ final class ConpherenceTransaction extends PhabricatorApplicationTransaction {
}
return $title;
break;
case ConpherenceTransactionType::TYPE_PARTICIPANTS:
case self::TYPE_PARTICIPANTS:
$add = array_diff($new, $old);
$rem = array_diff($old, $new);
@ -124,7 +131,7 @@ final class ConpherenceTransaction extends PhabricatorApplicationTransaction {
$new = $this->getNewValue();
switch ($this->getTransactionType()) {
case ConpherenceTransactionType::TYPE_TITLE:
case self::TYPE_TITLE:
if ($old && $new) {
$title = pht(
'%s renamed this room from "%s" to "%s".',
@ -144,7 +151,7 @@ final class ConpherenceTransaction extends PhabricatorApplicationTransaction {
}
return $title;
break;
case ConpherenceTransactionType::TYPE_PICTURE:
case self::TYPE_PICTURE:
return pht(
'%s updated the room image.',
$this->renderHandleLink($author_phid));
@ -180,7 +187,7 @@ final class ConpherenceTransaction extends PhabricatorApplicationTransaction {
$new = $this->getNewValue();
switch ($this->getTransactionType()) {
case ConpherenceTransactionType::TYPE_TITLE:
case self::TYPE_TITLE:
if ($old && $new) {
$title = pht(
'%s renamed this thread from "%s" to "%s".',
@ -200,7 +207,7 @@ final class ConpherenceTransaction extends PhabricatorApplicationTransaction {
}
return $title;
break;
case ConpherenceTransactionType::TYPE_PICTURE:
case self::TYPE_PICTURE:
return pht(
'%s updated the room image.',
$this->renderHandleLink($author_phid));
@ -237,12 +244,12 @@ final class ConpherenceTransaction extends PhabricatorApplicationTransaction {
$phids[] = $this->getAuthorPHID();
switch ($this->getTransactionType()) {
case ConpherenceTransactionType::TYPE_TITLE:
case ConpherenceTransactionType::TYPE_PICTURE:
case ConpherenceTransactionType::TYPE_FILES:
case ConpherenceTransactionType::TYPE_DATE_MARKER:
case self::TYPE_TITLE:
case self::TYPE_PICTURE:
case self::TYPE_FILES:
case self::TYPE_DATE_MARKER:
break;
case ConpherenceTransactionType::TYPE_PARTICIPANTS:
case self::TYPE_PARTICIPANTS:
$phids = array_merge($phids, $this->getOldValue());
$phids = array_merge($phids, $this->getNewValue());
break;

View file

@ -6,14 +6,9 @@ final class ConpherenceTransactionView extends AphrontView {
private $conpherenceTransaction;
private $handles;
private $markupEngine;
private $epoch;
private $epochHref;
private $contentSource;
private $anchorName;
private $anchorText;
private $fullDisplay;
private $classes = array();
private $timeOnly;
private $showImages = true;
public function setConpherenceThread(ConpherenceThread $t) {
$this->conpherenceThread = $t;
@ -52,25 +47,13 @@ final class ConpherenceTransactionView extends AphrontView {
return $this->markupEngine;
}
public function setEpoch($epoch, $epoch_href = null) {
$this->epoch = $epoch;
$this->epochHref = $epoch_href;
public function setFullDisplay($bool) {
$this->fullDisplay = $bool;
return $this;
}
public function setContentSource(PhabricatorContentSource $source) {
$this->contentSource = $source;
return $this;
}
private function getContentSource() {
return $this->contentSource;
}
public function setAnchor($anchor_name, $anchor_text) {
$this->anchorName = $anchor_name;
$this->anchorText = $anchor_text;
return $this;
private function getFullDisplay() {
return $this->fullDisplay;
}
public function addClass($class) {
@ -78,23 +61,9 @@ final class ConpherenceTransactionView extends AphrontView {
return $this;
}
public function setTimeOnly($time) {
$this->timeOnly = $time;
return $this;
}
public function setShowImages($bool) {
$this->showImages = $bool;
return $this;
}
private function getShowImages() {
return $this->showImages;
}
public function render() {
$user = $this->getUser();
if (!$user) {
$viewer = $this->getUser();
if (!$viewer) {
throw new Exception(pht('Call setUser() before render()!'));
}
@ -102,7 +71,7 @@ final class ConpherenceTransactionView extends AphrontView {
$transaction = $this->getConpherenceTransaction();
switch ($transaction->getTransactionType()) {
case ConpherenceTransactionType::TYPE_DATE_MARKER:
case ConpherenceTransaction::TYPE_DATE_MARKER:
return javelin_tag(
'div',
array(
@ -120,7 +89,7 @@ final class ConpherenceTransactionView extends AphrontView {
),
phabricator_format_local_time(
$transaction->getDateCreated(),
$user,
$viewer,
'M jS, Y')),
));
break;
@ -132,7 +101,10 @@ final class ConpherenceTransactionView extends AphrontView {
$content = $this->renderTransactionContent();
$classes = implode(' ', $this->classes);
$transaction_id = $this->anchorName ? 'anchor-'.$this->anchorName : null;
$transaction_dom_id = null;
if ($this->getFullDisplay()) {
$transaction_dom_id = 'anchor-'.$transaction->getID();
}
$header = phutil_tag_div(
'conpherence-transaction-header grouped',
@ -142,7 +114,7 @@ final class ConpherenceTransactionView extends AphrontView {
'div',
array(
'class' => 'conpherence-transaction-view '.$classes,
'id' => $transaction_id,
'id' => $transaction_dom_id,
'sigil' => 'conpherence-transaction-view',
'meta' => array(
'id' => $transaction->getID(),
@ -156,53 +128,60 @@ final class ConpherenceTransactionView extends AphrontView {
}
private function renderTransactionInfo() {
$viewer = $this->getUser();
$thread = $this->getConpherenceThread();
$transaction = $this->getConpherenceTransaction();
$info = array();
if ($this->getContentSource()) {
if ($this->getFullDisplay() && $transaction->getContentSource()) {
$content_source = id(new PhabricatorContentSourceView())
->setContentSource($this->getContentSource())
->setUser($this->user)
->setContentSource($transaction->getContentSource())
->setUser($viewer)
->render();
if ($content_source) {
$info[] = $content_source;
}
}
if ($this->epoch) {
if ($this->timeOnly) {
$epoch = phabricator_time($this->epoch, $this->user);
} else {
$epoch = phabricator_datetime($this->epoch, $this->user);
}
if ($this->epochHref) {
$epoch = phutil_tag(
'a',
array(
'href' => $this->epochHref,
'class' => 'epoch-link',
),
$epoch);
}
$info[] = $epoch;
}
if ($this->anchorName) {
Javelin::initBehavior('phabricator-tooltips');
$tip = phabricator_datetime($transaction->getDateCreated(), $viewer);
$label = phabricator_time($transaction->getDateCreated(), $viewer);
$width = 360;
if ($this->getFullDisplay()) {
Javelin::initBehavior('phabricator-watch-anchor');
$anchor = id(new PhabricatorAnchorView())
->setAnchorName($this->anchorName)
->setAnchorName($transaction->getID())
->render();
$info[] = hsprintf(
'%s%s',
$anchor,
phutil_tag(
javelin_tag(
'a',
array(
'href' => '#'.$this->anchorName,
'href' => '#'.$transaction->getID(),
'class' => 'anchor-link',
'sigil' => 'has-tooltip',
'meta' => array(
'tip' => $tip,
'size' => $width,
),
),
$this->anchorText));
$label));
} else {
$href = '/'.$thread->getMonogram().'#'.$transaction->getID();
$info[] = javelin_tag(
'a',
array(
'href' => $href,
'class' => 'epoch-link',
'sigil' => 'has-tooltip',
'meta' => array(
'tip' => $tip,
'size' => $width,
),
),
$label);
}
$info = phutil_implode_html(" \xC2\xB7 ", $info);
@ -234,7 +213,7 @@ final class ConpherenceTransactionView extends AphrontView {
private function renderTransactionImage() {
$image = null;
if ($this->getShowImages()) {
if ($this->getFullDisplay()) {
$transaction = $this->getConpherenceTransaction();
switch ($transaction->getTransactionType()) {
case PhabricatorTransactions::TYPE_COMMENT:
@ -260,13 +239,13 @@ final class ConpherenceTransactionView extends AphrontView {
$content = null;
$handles = $this->getHandles();
switch ($transaction->getTransactionType()) {
case ConpherenceTransactionType::TYPE_FILES:
case ConpherenceTransaction::TYPE_FILES:
$content = $transaction->getTitle();
break;
case ConpherenceTransactionType::TYPE_TITLE:
case ConpherenceTransactionType::TYPE_PICTURE:
case ConpherenceTransactionType::TYPE_PICTURE_CROP:
case ConpherenceTransactionType::TYPE_PARTICIPANTS:
case ConpherenceTransaction::TYPE_TITLE:
case ConpherenceTransaction::TYPE_PICTURE:
case ConpherenceTransaction::TYPE_PICTURE_CROP:
case ConpherenceTransaction::TYPE_PARTICIPANTS:
case PhabricatorTransactions::TYPE_VIEW_POLICY:
case PhabricatorTransactions::TYPE_EDIT_POLICY:
case PhabricatorTransactions::TYPE_JOIN_POLICY:
@ -282,7 +261,7 @@ final class ConpherenceTransactionView extends AphrontView {
$comment,
PhabricatorApplicationTransactionComment::MARKUP_FIELD_COMMENT);
$content_class = 'conpherence-message';
break;
break;
}
$this->appendChild(

View file

@ -5,7 +5,7 @@ abstract class PhabricatorDaemonManagementWorkflow
private $runDaemonsAsUser = null;
protected final function loadAvailableDaemonClasses() {
final protected function loadAvailableDaemonClasses() {
$loader = new PhutilSymbolLoader();
return $loader
->setAncestorClass('PhutilDaemon')
@ -13,12 +13,12 @@ abstract class PhabricatorDaemonManagementWorkflow
->selectSymbolsWithoutLoading();
}
protected final function getPIDDirectory() {
final protected function getPIDDirectory() {
$path = PhabricatorEnv::getEnvConfig('phd.pid-directory');
return $this->getControlDirectory($path);
}
protected final function getLogDirectory() {
final protected function getLogDirectory() {
$path = PhabricatorEnv::getEnvConfig('phd.log-directory');
return $this->getControlDirectory($path);
}
@ -42,7 +42,7 @@ abstract class PhabricatorDaemonManagementWorkflow
return $path;
}
protected final function loadRunningDaemons() {
final protected function loadRunningDaemons() {
$daemons = array();
$pid_dir = $this->getPIDDirectory();
@ -56,7 +56,7 @@ abstract class PhabricatorDaemonManagementWorkflow
return array_mergev($daemons);
}
protected final function loadAllRunningDaemons() {
final protected function loadAllRunningDaemons() {
$local_daemons = $this->loadRunningDaemons();
$local_ids = array();
@ -114,7 +114,7 @@ abstract class PhabricatorDaemonManagementWorkflow
return head($match);
}
protected final function launchDaemons(
final protected function launchDaemons(
array $daemons,
$debug,
$run_as_current_user = false) {
@ -307,7 +307,7 @@ abstract class PhabricatorDaemonManagementWorkflow
/* -( Commands )----------------------------------------------------------- */
protected final function executeStartCommand(array $options) {
final protected function executeStartCommand(array $options) {
PhutilTypeSpec::checkMap(
$options,
array(
@ -377,7 +377,7 @@ abstract class PhabricatorDaemonManagementWorkflow
return 0;
}
protected final function executeStopCommand(
final protected function executeStopCommand(
array $pids,
array $options) {
@ -454,7 +454,7 @@ abstract class PhabricatorDaemonManagementWorkflow
return 0;
}
protected final function executeReloadCommand(array $pids) {
final protected function executeReloadCommand(array $pids) {
$console = PhutilConsole::getConsole();
$daemons = $this->loadRunningDaemons();

View file

@ -78,7 +78,6 @@ final class DifferentialSubscribersField
array(
PhabricatorPeopleUserPHIDType::TYPECONST,
PhabricatorProjectProjectPHIDType::TYPECONST,
PhabricatorMailingListListPHIDType::TYPECONST,
));
}

View file

@ -1258,19 +1258,19 @@ final class DifferentialTransactionEditor
public function getMailTagsMap() {
return array(
MetaMTANotificationType::TYPE_DIFFERENTIAL_REVIEW_REQUEST =>
DifferentialTransaction::MAILTAG_REVIEW_REQUEST =>
pht('A revision is created.'),
MetaMTANotificationType::TYPE_DIFFERENTIAL_UPDATED =>
DifferentialTransaction::MAILTAG_UPDATED =>
pht('A revision is updated.'),
MetaMTANotificationType::TYPE_DIFFERENTIAL_COMMENT =>
DifferentialTransaction::MAILTAG_COMMENT =>
pht('Someone comments on a revision.'),
MetaMTANotificationType::TYPE_DIFFERENTIAL_CLOSED =>
DifferentialTransaction::MAILTAG_CLOSED =>
pht('A revision is closed.'),
MetaMTANotificationType::TYPE_DIFFERENTIAL_REVIEWERS =>
DifferentialTransaction::MAILTAG_REVIEWERS =>
pht("A revision's reviewers change."),
MetaMTANotificationType::TYPE_DIFFERENTIAL_CC =>
DifferentialTransaction::MAILTAG_CC =>
pht("A revision's CCs change."),
MetaMTANotificationType::TYPE_DIFFERENTIAL_OTHER =>
DifferentialTransaction::MAILTAG_OTHER =>
pht('Other revision activity not listed above occurs.'),
);
}
@ -1554,13 +1554,6 @@ final class DifferentialTransactionEditor
PhabricatorLiskDAO $object,
array $xactions) {
$unsubscribed_phids = PhabricatorEdgeQuery::loadDestinationPHIDs(
$object->getPHID(),
PhabricatorObjectHasUnsubscriberEdgeType::EDGECONST);
$subscribed_phids = PhabricatorSubscribersQuery::loadSubscribersForPHID(
$object->getPHID());
$revision = id(new DifferentialRevisionQuery())
->setViewer($this->getActor())
->withPHIDs(array($object->getPHID()))
@ -1579,9 +1572,7 @@ final class DifferentialTransactionEditor
$reviewers = $revision->getReviewerStatus();
$reviewer_phids = mpull($reviewers, 'getReviewerPHID');
$adapter->setExplicitCCs($subscribed_phids);
$adapter->setExplicitReviewers($reviewer_phids);
$adapter->setForbiddenCCs($unsubscribed_phids);
return $adapter;
}
@ -1593,24 +1584,6 @@ final class DifferentialTransactionEditor
$xactions = array();
// Build a transaction to adjust CCs.
$ccs = array(
'+' => array_keys($adapter->getCCsAddedByHerald()),
'-' => array_keys($adapter->getCCsRemovedByHerald()),
);
$value = array();
foreach ($ccs as $type => $phids) {
foreach ($phids as $phid) {
$value[$type][$phid] = $phid;
}
}
if ($value) {
$xactions[] = id(new DifferentialTransaction())
->setTransactionType(PhabricatorTransactions::TYPE_SUBSCRIBERS)
->setNewValue($value);
}
// Build a transaction to adjust reviewers.
$reviewers = array(
DifferentialReviewerStatus::STATUS_ADDED =>
@ -1902,4 +1875,25 @@ final class DifferentialTransactionEditor
return $section;
}
protected function willPublish(PhabricatorLiskDAO $object, array $xactions) {
// Reload to pick up the active diff and reviewer status.
return id(new DifferentialRevisionQuery())
->setViewer($this->getActor())
->needReviewerStatus(true)
->needActiveDiffs(true)
->withIDs(array($object->getID()))
->executeOne();
}
protected function getCustomWorkerState() {
return array(
'changedPriorToCommitURI' => $this->changedPriorToCommitURI,
);
}
protected function loadCustomWorkerState(array $state) {
$this->changedPriorToCommitURI = idx($state, 'changedPriorToCommitURI');
return $this;
}
}

View file

@ -2,7 +2,7 @@
abstract class DifferentialLandingStrategy {
public abstract function processLandRequest(
abstract public function processLandRequest(
AphrontRequest $request,
DifferentialRevision $revision,
PhabricatorRepository $repository);
@ -10,7 +10,7 @@ abstract class DifferentialLandingStrategy {
/**
* @return PhabricatorActionView or null.
*/
public abstract function createMenuItem(
abstract public function createMenuItem(
PhabricatorUser $viewer,
DifferentialRevision $revision,
PhabricatorRepository $repository);

View file

@ -225,7 +225,7 @@ final class DifferentialChangesetOneUpRenderer
'file' => $new_file,
'line' => 1,
'oline' => ($old_file ? 1 : null),
'render' => $this->renderImageStage($old_file),
'render' => $this->renderImageStage($new_file),
);
}

View file

@ -37,7 +37,6 @@ final class DifferentialDiff
private $unsavedChangesets = array();
private $changesets = self::ATTACHABLE;
private $arcanistProject = self::ATTACHABLE;
private $revision = self::ATTACHABLE;
private $properties = array();
@ -108,25 +107,6 @@ final class DifferentialDiff
$this->getID());
}
public function attachArcanistProject(
PhabricatorRepositoryArcanistProject $project = null) {
$this->arcanistProject = $project;
return $this;
}
public function getArcanistProject() {
return $this->assertAttached($this->arcanistProject);
}
public function getArcanistProjectName() {
$name = '';
if ($this->arcanistProject) {
$project = $this->getArcanistProject();
$name = $project->getName();
}
return $name;
}
public function save() {
$this->openTransaction();
$ret = parent::save();

View file

@ -4,6 +4,7 @@ final class DifferentialRevision extends DifferentialDAO
implements
PhabricatorTokenReceiverInterface,
PhabricatorPolicyInterface,
PhabricatorExtendedPolicyInterface,
PhabricatorFlaggableInterface,
PhrequentTrackableInterface,
HarbormasterBuildableInterface,
@ -64,6 +65,7 @@ final class DifferentialRevision extends DifferentialDAO
->setViewPolicy($view_policy)
->setAuthorPHID($actor->getPHID())
->attachRelationships(array())
->attachRepository(null)
->setStatus(ArcanistDifferentialRevisionStatus::NEEDS_REVIEW);
}
@ -280,6 +282,10 @@ final class DifferentialRevision extends DifferentialDAO
return $this;
}
/* -( PhabricatorPolicyInterface )----------------------------------------- */
public function getCapabilities() {
return array(
PhabricatorPolicyCapability::CAN_VIEW,
@ -326,6 +332,45 @@ final class DifferentialRevision extends DifferentialDAO
return $description;
}
/* -( PhabricatorExtendedPolicyInterface )--------------------------------- */
public function getExtendedPolicy($capability, PhabricatorUser $viewer) {
$extended = array();
switch ($capability) {
case PhabricatorPolicyCapability::CAN_VIEW:
// NOTE: In Differential, an automatic capability on a revision (being
// an author) is sufficient to view it, even if you can not see the
// repository the revision belongs to. We can bail out early in this
// case.
if ($this->hasAutomaticCapability($capability, $viewer)) {
break;
}
$repository_phid = $this->getRepositoryPHID();
$repository = $this->getRepository();
// Try to use the object if we have it, since it will save us some
// data fetching later on. In some cases, we might not have it.
$repository_ref = nonempty($repository, $repository_phid);
if ($repository_ref) {
$extended[] = array(
$repository_ref,
PhabricatorPolicyCapability::CAN_VIEW,
);
}
break;
}
return $extended;
}
/* -( PhabricatorTokenReceiverInterface )---------------------------------- */
public function getUsersToNotifyOfTokenGiven() {
return array(
$this->getAuthorPHID(),

View file

@ -4,6 +4,19 @@ final class DifferentialTransaction extends PhabricatorApplicationTransaction {
private $isCommandeerSideEffect;
const TYPE_INLINE = 'differential:inline';
const TYPE_UPDATE = 'differential:update';
const TYPE_ACTION = 'differential:action';
const TYPE_STATUS = 'differential:status';
const MAILTAG_REVIEWERS = 'differential-reviewers';
const MAILTAG_CLOSED = 'differential-committed';
const MAILTAG_CC = 'differential-cc';
const MAILTAG_COMMENT = 'differential-comment';
const MAILTAG_UPDATED = 'differential-updated';
const MAILTAG_REVIEW_REQUEST = 'differential-review-request';
const MAILTAG_OTHER = 'differential-other';
public function setIsCommandeerSideEffect($is_side_effect) {
$this->isCommandeerSideEffect = $is_side_effect;
@ -14,11 +27,6 @@ final class DifferentialTransaction extends PhabricatorApplicationTransaction {
return $this->isCommandeerSideEffect;
}
const TYPE_INLINE = 'differential:inline';
const TYPE_UPDATE = 'differential:update';
const TYPE_ACTION = 'differential:action';
const TYPE_STATUS = 'differential:status';
public function getApplicationName() {
return 'differential';
}
@ -109,7 +117,6 @@ final class DifferentialTransaction extends PhabricatorApplicationTransaction {
}
public function getActionStrength() {
switch ($this->getTransactionType()) {
case self::TYPE_ACTION:
return 3;
@ -160,38 +167,38 @@ final class DifferentialTransaction extends PhabricatorApplicationTransaction {
switch ($this->getTransactionType()) {
case PhabricatorTransactions::TYPE_SUBSCRIBERS;
$tags[] = MetaMTANotificationType::TYPE_DIFFERENTIAL_CC;
$tags[] = self::MAILTAG_CC;
break;
case self::TYPE_ACTION:
switch ($this->getNewValue()) {
case DifferentialAction::ACTION_CLOSE:
$tags[] = MetaMTANotificationType::TYPE_DIFFERENTIAL_CLOSED;
$tags[] = self::MAILTAG_CLOSED;
break;
}
break;
case self::TYPE_UPDATE:
$old = $this->getOldValue();
if ($old === null) {
$tags[] = MetaMTANotificationType::TYPE_DIFFERENTIAL_REVIEW_REQUEST;
$tags[] = self::MAILTAG_REVIEW_REQUEST;
} else {
$tags[] = MetaMTANotificationType::TYPE_DIFFERENTIAL_UPDATED;
$tags[] = self::MAILTAG_UPDATED;
}
break;
case PhabricatorTransactions::TYPE_EDGE:
switch ($this->getMetadataValue('edge:type')) {
case DifferentialRevisionHasReviewerEdgeType::EDGECONST:
$tags[] = MetaMTANotificationType::TYPE_DIFFERENTIAL_REVIEWERS;
$tags[] = self::MAILTAG_REVIEWERS;
break;
}
break;
case PhabricatorTransactions::TYPE_COMMENT:
case self::TYPE_INLINE:
$tags[] = MetaMTANotificationType::TYPE_DIFFERENTIAL_COMMENT;
$tags[] = self::MAILTAG_COMMENT;
break;
}
if (!$tags) {
$tags[] = MetaMTANotificationType::TYPE_DIFFERENTIAL_OTHER;
$tags[] = self::MAILTAG_OTHER;
}
return $tags;
@ -280,7 +287,7 @@ final class DifferentialTransaction extends PhabricatorApplicationTransaction {
case ArcanistDifferentialRevisionStatus::NEEDS_REVIEW:
return pht('This revision now requires review to proceed.');
}
}
}
return parent::getTitle();
}
@ -438,7 +445,7 @@ final class DifferentialTransaction extends PhabricatorApplicationTransaction {
'%s now requires review to proceed.',
$object_link);
}
}
}
return parent::getTitleForFeed();
}

View file

@ -190,7 +190,7 @@ final class DifferentialChangesetListView extends AphrontView {
} else {
$detail->setAutoload(isset($this->visibleChangesets[$key]));
if (isset($this->visibleChangesets[$key])) {
$load = 'Loading...';
$load = pht('Loading...');
} else {
$load = javelin_tag(
'a',

View file

@ -78,7 +78,7 @@ final class DifferentialResultsTableView extends AphrontView {
'href' => '#',
'mustcapture' => true,
),
'Hide');
pht('Hide'));
$rows[] = javelin_tag(
'tr',

View file

@ -36,15 +36,14 @@ final class DifferentialRevisionUpdateHistoryView extends AphrontView {
}
public function render() {
$this->requireResource('differential-core-view-css');
$this->requireResource('differential-revision-history-css');
$data = array(
array(
'name' => 'Base',
'name' => pht('Base'),
'id' => null,
'desc' => 'Base',
'desc' => pht('Base'),
'age' => null,
'obj' => null,
),
@ -53,7 +52,7 @@ final class DifferentialRevisionUpdateHistoryView extends AphrontView {
$seq = 0;
foreach ($this->diffs as $diff) {
$data[] = array(
'name' => 'Diff '.(++$seq),
'name' => pht('Diff %d', ++$seq),
'id' => $diff->getID(),
'desc' => $diff->getDescription(),
'age' => $diff->getDateCreated(),

View file

@ -116,7 +116,7 @@ final class DiffusionLintController extends DiffusionController {
->setValue($owners))
->appendChild(
id(new AphrontFormSubmitControl())
->setValue('Filter'));
->setValue(pht('Filter')));
$content[] = id(new AphrontListFilterView())->appendChild($form);
}

View file

@ -181,7 +181,7 @@ final class DiffusionRepositoryEditHostingController
'%s: This repository is hosted elsewhere, so Phabricator can not '.
'perform writes. This mode will act like "Read Only" for '.
'repositories hosted elsewhere.',
phutil_tag('strong', array(), 'WARNING')),
phutil_tag('strong', array(), pht('WARNING'))),
);
}

View file

@ -12,7 +12,7 @@ final class DiffusionSymbolController extends DiffusionController {
->setViewer($user)
->setName($this->name);
if ($request->getStr('context') !== null) {
if ($request->getStr('context')) {
$query->setContext($request->getStr('context'));
}
@ -47,63 +47,69 @@ final class DiffusionSymbolController extends DiffusionController {
$symbols = $query->execute();
// For PHP builtins, jump to php.net documentation.
if ($request->getBool('jump') && count($symbols) == 0) {
if ($request->getStr('lang', 'php') == 'php') {
if ($request->getStr('type', 'function') == 'function') {
$functions = get_defined_functions();
if (in_array($this->name, $functions['internal'])) {
return id(new AphrontRedirectResponse())
->setIsExternal(true)
->setURI('http://www.php.net/function.'.$this->name);
}
}
if ($request->getStr('type', 'class') == 'class') {
if (class_exists($this->name, false) ||
interface_exists($this->name, false)) {
if (id(new ReflectionClass($this->name))->isInternal()) {
return id(new AphrontRedirectResponse())
->setIsExternal(true)
->setURI('http://www.php.net/class.'.$this->name);
}
}
}
}
$external_query = id(new DiffusionExternalSymbolQuery())
->withNames(array($this->name));
if ($request->getStr('context')) {
$external_query->withContexts(array($request->getStr('context')));
}
if ($request->getStr('type')) {
$external_query->withTypes(array($request->getStr('type')));
}
if ($request->getStr('lang')) {
$external_query->withLanguages(array($request->getStr('lang')));
}
$external_sources = id(new PhutilSymbolLoader())
->setAncestorClass('DiffusionExternalSymbolsSource')
->loadObjects();
$results = array($symbols);
foreach ($external_sources as $source) {
$results[] = $source->executeQuery($external_query);
}
$symbols = array_mergev($results);
if ($request->getBool('jump') && count($symbols) == 1) {
// If this is a clickthrough from Differential, just jump them
// straight to the target if we got a single hit.
$symbol = head($symbols);
return id(new AphrontRedirectResponse())
->setIsExternal($symbol->isExternal())
->setURI($symbol->getURI());
}
$rows = array();
foreach ($symbols as $symbol) {
$file = $symbol->getPath();
$line = $symbol->getLineNumber();
$href = $symbol->getURI();
$repo = $symbol->getRepository();
if ($repo) {
$href = $symbol->getURI();
if ($request->getBool('jump') && count($symbols) == 1) {
// If this is a clickthrough from Differential, just jump them
// straight to the target if we got a single hit.
return id(new AphrontRedirectResponse())->setURI($href);
}
$location = phutil_tag(
'a',
array(
'href' => $href,
),
$file.':'.$line);
} else if ($file) {
$location = $file.':'.$line;
if ($symbol->isExternal()) {
$source = $symbol->getSource();
$location = $symbol->getLocation();
} else {
$location = '?';
$repo = $symbol->getRepository();
$file = $symbol->getPath();
$line = $symbol->getLineNumber();
$source = $repo->getMonogram();
$location = $file.':'.$line;
}
$location = phutil_tag(
'a',
array(
'href' => $href,
),
$location);
$rows[] = array(
$symbol->getSymbolType(),
$symbol->getSymbolContext(),
$symbol->getSymbolName(),
$symbol->getSymbolLanguage(),
$repo->getMonogram(),
$source,
$location,
);
}
@ -115,8 +121,8 @@ final class DiffusionSymbolController extends DiffusionController {
pht('Context'),
pht('Name'),
pht('Language'),
pht('Repository'),
pht('File'),
pht('Source'),
pht('Location'),
));
$table->setColumnClasses(
array(

View file

@ -19,7 +19,7 @@ final class DiffusionCommitRevertedByCommitEdgeType
$add_edges) {
return pht(
'%s added %s reverted commit(s): %s.',
'%s added %s reverting commit(s): %s.',
$actor,
$add_count,
$add_edges);
@ -31,7 +31,7 @@ final class DiffusionCommitRevertedByCommitEdgeType
$rem_edges) {
return pht(
'%s removed %s reverted commit(s): %s.',
'%s removed %s reverting commit(s): %s.',
$actor,
$rem_count,
$rem_edges);
@ -46,7 +46,7 @@ final class DiffusionCommitRevertedByCommitEdgeType
$rem_edges) {
return pht(
'%s edited reverted commit(s), added %s: %s; removed %s: %s.',
'%s edited reverting commit(s), added %s: %s; removed %s: %s.',
$actor,
$add_count,
$add_edges,
@ -61,7 +61,7 @@ final class DiffusionCommitRevertedByCommitEdgeType
$add_edges) {
return pht(
'%s added %s reverted commit(s) for %s: %s.',
'%s added %s reverting commit(s) for %s: %s.',
$actor,
$add_count,
$object,
@ -75,7 +75,7 @@ final class DiffusionCommitRevertedByCommitEdgeType
$rem_edges) {
return pht(
'%s removed %s reverted commit(s) for %s: %s.',
'%s removed %s reverting commit(s) for %s: %s.',
$actor,
$rem_count,
$object,
@ -92,7 +92,7 @@ final class DiffusionCommitRevertedByCommitEdgeType
$rem_edges) {
return pht(
'%s edited reverted commit(s) for %s, added %s: %s; removed %s: %s.',
'%s edited reverting commit(s) for %s, added %s: %s; removed %s: %s.',
$actor,
$object,
$add_count,

View file

@ -22,7 +22,7 @@ final class DiffusionCommitRevertsCommitEdgeType extends PhabricatorEdgeType {
$add_edges) {
return pht(
'%s added %s reverting commit(s): %s.',
'%s added %s reverted commit(s): %s.',
$actor,
$add_count,
$add_edges);
@ -34,7 +34,7 @@ final class DiffusionCommitRevertsCommitEdgeType extends PhabricatorEdgeType {
$rem_edges) {
return pht(
'%s removed %s reverting commit(s): %s.',
'%s removed %s reverted commit(s): %s.',
$actor,
$rem_count,
$rem_edges);
@ -49,7 +49,7 @@ final class DiffusionCommitRevertsCommitEdgeType extends PhabricatorEdgeType {
$rem_edges) {
return pht(
'%s edited reverting commit(s), added %s: %s; removed %s: %s.',
'%s edited reverted commit(s), added %s: %s; removed %s: %s.',
$actor,
$add_count,
$add_edges,
@ -64,7 +64,7 @@ final class DiffusionCommitRevertsCommitEdgeType extends PhabricatorEdgeType {
$add_edges) {
return pht(
'%s added %s reverting commit(s) for %s: %s.',
'%s added %s reverted commit(s) for %s: %s.',
$actor,
$add_count,
$object,
@ -78,7 +78,7 @@ final class DiffusionCommitRevertsCommitEdgeType extends PhabricatorEdgeType {
$rem_edges) {
return pht(
'%s removed %s reverting commit(s) for %s: %s.',
'%s removed %s reverted commit(s) for %s: %s.',
$actor,
$rem_count,
$object,
@ -95,7 +95,7 @@ final class DiffusionCommitRevertsCommitEdgeType extends PhabricatorEdgeType {
$rem_edges) {
return pht(
'%s edited reverting commit(s) for %s, added %s: %s; removed %s: %s.',
'%s edited reverted commit(s) for %s, added %s: %s; removed %s: %s.',
$actor,
$object,
$add_count,

View file

@ -95,12 +95,6 @@ abstract class HeraldPreCommitAdapter extends HeraldAdapter {
foreach ($effects as $effect) {
$action = $effect->getAction();
switch ($action) {
case self::ACTION_NOTHING:
$result[] = new HeraldApplyTranscript(
$effect,
true,
pht('Did nothing.'));
break;
case self::ACTION_BLOCK:
$result[] = new HeraldApplyTranscript(
$effect,

View file

@ -19,6 +19,10 @@ final class DiffusionSetPasswordSettingsPanel extends PhabricatorSettingsPanel {
}
public function isEnabled() {
if ($this->getUser()->getIsMailingList()) {
return false;
}
return PhabricatorEnv::getEnvConfig('diffusion.allow-http-auth');
}

View file

@ -0,0 +1,46 @@
<?php
final class DiffusionExternalSymbolQuery {
private $languages = array();
private $types = array();
private $names = array();
private $contexts = array();
public function withLanguages(array $languages) {
$this->languages = $languages;
return $this;
}
public function withTypes(array $types) {
$this->types = $types;
return $this;
}
public function withNames(array $names) {
$this->names = $names;
return $this;
}
public function withContexts(array $contexts) {
$this->contexts = $contexts;
return $this;
}
public function getLanguages() {
return $this->languages;
}
public function getTypes() {
return $this->types;
}
public function getNames() {
return $this->names;
}
public function getContexts() {
return $this->contexts;
}
public function matchesAnyLanguage(array $languages) {
return (!$this->languages) || array_intersect($languages, $this->languages);
}
public function matchesAnyType(array $types) {
return (!$this->types) || array_intersect($types, $this->types);
}
}

View file

@ -0,0 +1,15 @@
<?php
abstract class DiffusionExternalSymbolsSource {
/**
* @return list of PhabricatorRepositorySymbol
*/
abstract public function executeQuery(DiffusionExternalSymbolQuery $query);
protected function buildExternalSymbol() {
return id(new PhabricatorRepositorySymbol())
->setIsExternal(true)
->makeEphemeral();
}
}

View file

@ -0,0 +1,49 @@
<?php
final class DiffusionPhpExternalSymbolsSource
extends DiffusionExternalSymbolsSource {
public function executeQuery(DiffusionExternalSymbolQuery $query) {
$symbols = array();
if (!$query->matchesAnyLanguage(array('php'))) {
return $symbols;
}
$names = $query->getNames();
if ($query->matchesAnyType(array('function'))) {
$functions = get_defined_functions();
$functions = $functions['internal'];
foreach ($names as $name) {
if (in_array($name, $functions)) {
$symbols[] = $this->buildExternalSymbol()
->setSymbolName($name)
->setSymbolType('function')
->setSource(pht('PHP'))
->setLocation(pht('Manual at php.net'))
->setSymbolLanguage('php')
->setExternalURI('http://www.php.net/function.'.$name);
}
}
}
if ($query->matchesAnyType(array('class'))) {
foreach ($names as $name) {
if (class_exists($name, false) || interface_exists($name, false)) {
if (id(new ReflectionClass($name))->isInternal()) {
$symbols[] = $this->buildExternalSymbol()
->setSymbolName($name)
->setSymbolType('class')
->setSource(pht('PHP'))
->setLocation(pht('Manual at php.net'))
->setSymbolLanguage('php')
->setExternalURI('http://www.php.net/class.'.$name);
}
}
}
}
return $symbols;
}
}

View file

@ -0,0 +1,134 @@
<?php
final class DiffusionPythonExternalSymbolsSource
extends DiffusionExternalSymbolsSource {
public function executeQuery(DiffusionExternalSymbolQuery $query) {
$symbols = array();
if (!$query->matchesAnyLanguage(array('py', 'python'))) {
return $symbols;
}
if (!$query->matchesAnyType(array('builtin', 'function'))) {
return $symbols;
}
$names = $query->getNames();
foreach ($names as $name) {
if (idx(self::$python2Builtins, $name)) {
$symbols[] = $this->buildExternalSymbol()
->setSymbolName($name)
->setSymbolType('function')
->setSource(pht('Standard Library'))
->setLocation(pht('The Python 2 Standard Library'))
->setSymbolLanguage('py')
->setExternalURI(
'https://docs.python.org/2/library/functions.html#'.$name);
}
if (idx(self::$python3Builtins, $name)) {
$symbols[] = $this->buildExternalSymbol()
->setSymbolName($name)
->setSymbolType('function')
->setSource(pht('Standard Library'))
->setLocation(pht('The Python 3 Standard Library'))
->setSymbolLanguage('py')
->setExternalURI(
'https://docs.python.org/3/library/functions.html#'.$name);
}
}
return $symbols;
}
private static $python2Builtins = array(
'__import__' => true,
'abs' => true,
'all' => true,
'any' => true,
'basestring' => true,
'bin' => true,
'bool' => true,
'bytearray' => true,
'callable' => true,
'chr' => true,
'classmethod' => true,
'cmp' => true,
'compile' => true,
'complex' => true,
'delattr' => true,
'dict' => true,
'dir' => true,
'divmod' => true,
'enumerate' => true,
'eval' => true,
'execfile' => true,
'file' => true,
'filter' => true,
'float' => true,
'format' => true,
'frozenset' => true,
'getattr' => true,
'globals' => true,
'hasattr' => true,
'hash' => true,
'help' => true,
'hex' => true,
'id' => true,
'input' => true,
'int' => true,
'isinstance' => true,
'issubclass' => true,
'iter' => true,
'len' => true,
'list' => true,
'locals' => true,
'long' => true,
'map' => true,
'max' => true,
'memoryview' => true,
'min' => true,
'next' => true,
'object' => true,
'oct' => true,
'open' => true,
'ord' => true,
'pow' => true,
'print' => true,
'property' => true,
'range' => true,
'raw_input' => true,
'reduce' => true,
'reload' => true,
'repr' => true,
'reversed' => true,
'round' => true,
'set' => true,
'setattr' => true,
'slice' => true,
'sorted' => true,
'staticmethod' => true,
'str' => true,
'sum' => true,
'super' => true,
'tuple' => true,
'type' => true,
'unichr' => true,
'unicode' => true,
'vars' => true,
'xrange' => true,
'zip' => true,
);
// This list only contains functions that are new or changed between the
// Python versions.
private static $python3Builtins = array(
'ascii' => true,
'bytes' => true,
'filter' => true,
'map' => true,
'next' => true,
'range' => true,
'super' => true,
'zip' => true,
);
}

View file

@ -149,7 +149,7 @@ final class DiffusionHistoryTableView extends DiffusionView {
$summary = AphrontTableView::renderSingleDisplayLine(
$history->getSummary());
} else {
$summary = phutil_tag('em', array(), "Importing\xE2\x80\xA6");
$summary = phutil_tag('em', array(), pht("Importing\xE2\x80\xA6"));
}
$build = null;

View file

@ -58,4 +58,11 @@ final class PhabricatorDivinerApplication extends PhabricatorApplication {
);
}
public function getApplicationSearchDocumentTypes() {
return array(
DivinerAtomPHIDType::TYPECONST,
DivinerBookPHIDType::TYPECONST,
);
}
}

View file

@ -35,11 +35,6 @@ final class DivinerAtomController extends DivinerController {
return new Aphront404Response();
}
// TODO: This query won't load ghosts, because they'll fail `needAtoms()`.
// Instead, we might want to load ghosts and render a message like
// "this thing existed in an older version, but no longer does", especially
// if we add content like comments.
$symbol = id(new DivinerAtomQuery())
->setViewer($viewer)
->withBookPHIDs(array($book->getPHID()))
@ -47,6 +42,7 @@ final class DivinerAtomController extends DivinerController {
->withNames(array($this->atomName))
->withContexts(array($this->atomContext))
->withIndexes(array($this->atomIndex))
->withIsDocumentable(true)
->needAtoms(true)
->needExtends(true)
->needChildren(true)
@ -64,9 +60,9 @@ final class DivinerAtomController extends DivinerController {
$book->getShortTitle(),
'/book/'.$book->getName().'/');
$atom_short_title = $atom->getDocblockMetaValue(
'short',
$symbol->getTitle());
$atom_short_title = $atom
? $atom->getDocblockMetaValue('short', $symbol->getTitle())
: $symbol->getTitle();
$crumbs->addTextCrumb($atom_short_title);
@ -76,26 +72,38 @@ final class DivinerAtomController extends DivinerController {
id(new PHUITagView())
->setType(PHUITagView::TYPE_STATE)
->setBackgroundColor(PHUITagView::COLOR_BLUE)
->setName(DivinerAtom::getAtomTypeNameString($atom->getType())));
->setName(DivinerAtom::getAtomTypeNameString(
$atom ? $atom->getType() : $symbol->getType())));
$properties = id(new PHUIPropertyListView());
$group = $atom->getProperty('group');
$group = $atom ? $atom->getProperty('group') : $symbol->getGroupName();
if ($group) {
$group_name = $book->getGroupName($group);
} else {
$group_name = null;
}
$this->buildDefined($properties, $symbol);
$this->buildExtendsAndImplements($properties, $symbol);
$document = id(new PHUIDocumentView())
->setBook($book->getTitle(), $group_name)
->setHeader($header)
->addClass('diviner-view')
->setFontKit(PHUIDocumentView::FONT_SOURCE_SANS)
->appendChild($properties);
$warnings = $atom->getWarnings();
if ($warnings) {
$warnings = id(new PHUIInfoView())
->setErrors($warnings)
->setTitle(pht('Documentation Warnings'))
->setSeverity(PHUIInfoView::SEVERITY_WARNING);
if ($atom) {
$this->buildDefined($properties, $symbol);
$this->buildExtendsAndImplements($properties, $symbol);
$warnings = $atom->getWarnings();
if ($warnings) {
$warnings = id(new PHUIInfoView())
->setErrors($warnings)
->setTitle(pht('Documentation Warnings'))
->setSeverity(PHUIInfoView::SEVERITY_WARNING);
}
$document->appendChild($warnings);
}
$methods = $this->composeMethods($symbol);
@ -111,7 +119,10 @@ final class DivinerAtomController extends DivinerController {
}
$engine->process();
$content = $this->renderDocumentationText($symbol, $engine);
if ($atom) {
$content = $this->renderDocumentationText($symbol, $engine);
$document->appendChild($content);
}
$toc = $engine->getEngineMetadata(
$symbol,
@ -119,16 +130,18 @@ final class DivinerAtomController extends DivinerController {
PhutilRemarkupHeaderBlockRule::KEY_HEADER_TOC,
array());
$document = id(new PHUIDocumentView())
->setBook($book->getTitle(), $group_name)
->setHeader($header)
->addClass('diviner-view')
->setFontKit(PHUIDocumentView::FONT_SOURCE_SANS)
->appendChild($properties)
->appendChild($warnings)
->appendChild($content);
if (!$atom) {
$document->appendChild(
id(new PHUIInfoView())
->setSeverity(PHUIInfoView::SEVERITY_NOTICE)
->appendChild(
pht(
'This atom no longer exists.')));
}
$document->appendChild($this->buildParametersAndReturn(array($symbol)));
if ($atom) {
$document->appendChild($this->buildParametersAndReturn(array($symbol)));
}
if ($methods) {
$tasks = $this->composeTasks($symbol);
@ -200,7 +213,7 @@ final class DivinerAtomController extends DivinerController {
}
$section = id(new DivinerSectionView())
->setHeader(pht('Methods'));
->setHeader(pht('Methods'));
foreach ($methods as $spec) {
$matom = last($spec['atoms']);
@ -471,20 +484,23 @@ final class DivinerAtomController extends DivinerController {
$atom = $symbol->getAtom();
$out = array();
if ($atom->getProperty('final')) {
$out[] = 'final';
}
if ($atom->getProperty('abstract')) {
$out[] = 'abstract';
}
if ($atom) {
if ($atom->getProperty('final')) {
$out[] = 'final';
}
if ($atom->getProperty('access')) {
$out[] = $atom->getProperty('access');
}
if ($atom->getProperty('abstract')) {
$out[] = 'abstract';
}
if ($atom->getProperty('static')) {
$out[] = 'static';
if ($atom->getProperty('access')) {
$out[] = $atom->getProperty('access');
}
if ($atom->getProperty('static')) {
$out[] = 'static';
}
}
switch ($symbol->getType()) {
@ -528,13 +544,15 @@ final class DivinerAtomController extends DivinerController {
$out = phutil_implode_html(' ', $out);
$parameters = $atom->getProperty('parameters');
if ($parameters !== null) {
$pout = array();
foreach ($parameters as $parameter) {
$pout[] = idx($parameter, 'name', '...');
if ($atom) {
$parameters = $atom->getProperty('parameters');
if ($parameters !== null) {
$pout = array();
foreach ($parameters as $parameter) {
$pout[] = idx($parameter, 'name', '...');
}
$out = array($out, '('.implode(', ', $pout).')');
}
$out = array($out, '('.implode(', ', $pout).')');
}
return phutil_tag(

View file

@ -46,6 +46,8 @@ final class DivinerBookController extends DivinerController {
$atoms = id(new DivinerAtomQuery())
->setViewer($viewer)
->withBookPHIDs(array($book->getPHID()))
->withGhosts(false)
->withIsDocumentable(true)
->execute();
$atoms = msort($atoms, 'getSortKey');

View file

@ -41,6 +41,9 @@ final class DivinerFindController extends DivinerController {
$query->withTypes(array($type));
}
$query->withGhosts(false);
$query->withIsDocumentable(true);
$name_query = clone $query;
$name_query->withNames(

View file

@ -5,7 +5,7 @@ final class DivinerAtomPHIDType extends PhabricatorPHIDType {
const TYPECONST = 'ATOM';
public function getTypeName() {
return pht('Atom');
return pht('Diviner Atom');
}
public function newObject() {
@ -28,8 +28,17 @@ final class DivinerAtomPHIDType extends PhabricatorPHIDType {
foreach ($handles as $phid => $handle) {
$atom = $objects[$phid];
$handle->setName($atom->getTitle());
$handle->setURI($atom->getName());
$book = $atom->getBook()->getName();
$name = $atom->getName();
$type = $atom->getType();
$handle
->setName($atom->getName())
->setTitle($atom->getTitle())
->setURI("/book/{$book}/{$type}/{$name}/")
->setStatus($atom->getGraphHash()
? PhabricatorObjectHandle::STATUS_OPEN
: PhabricatorObjectHandle::STATUS_CLOSED);
}
}

View file

@ -5,7 +5,7 @@ final class DivinerBookPHIDType extends PhabricatorPHIDType {
const TYPECONST = 'BOOK';
public function getTypeName() {
return pht('Book');
return pht('Diviner Book');
}
public function newObject() {
@ -30,9 +30,10 @@ final class DivinerBookPHIDType extends PhabricatorPHIDType {
$name = $book->getName();
$handle->setName($book->getShortTitle());
$handle->setFullName($book->getTitle());
$handle->setURI("/diviner/book/{$name}/");
$handle
->setName($book->getShortTitle())
->setFullName($book->getTitle())
->setURI("/book/{$name}/");
}
}

View file

@ -18,6 +18,9 @@ final class DivinerLivePublisher extends DivinerPublisher {
$book->setConfigurationData($this->getConfigurationData())->save();
$this->book = $book;
id(new PhabricatorSearchIndexer())
->queueDocumentForIndexing($book->getPHID());
}
return $this->book;
@ -31,8 +34,6 @@ final class DivinerLivePublisher extends DivinerPublisher {
->withNames(array($atom->getName()))
->withContexts(array($atom->getContext()))
->withIndexes(array($this->getAtomSimilarIndex($atom)))
->withIncludeUndocumentable(true)
->withIncludeGhosts(true)
->executeOne();
if ($symbol) {
@ -64,7 +65,7 @@ final class DivinerLivePublisher extends DivinerPublisher {
$symbols = id(new DivinerAtomQuery())
->setViewer(PhabricatorUser::getOmnipotentUser())
->withBookPHIDs(array($this->loadBook()->getPHID()))
->withIncludeUndocumentable(true)
->withGhosts(false)
->execute();
return mpull($symbols, 'getGraphHash');
@ -124,6 +125,9 @@ final class DivinerLivePublisher extends DivinerPublisher {
$symbol->save();
id(new PhabricatorSearchIndexer())
->queueDocumentForIndexing($symbol->getPHID());
// TODO: We probably need a finer-grained sense of what "documentable"
// atoms are. Neither files nor methods are currently considered
// documentable, but for different reasons: files appear nowhere, while

View file

@ -10,42 +10,42 @@ abstract class DivinerPublisher {
private $symbolReverseMap;
private $dropCaches;
public final function setDropCaches($drop_caches) {
final public function setDropCaches($drop_caches) {
$this->dropCaches = $drop_caches;
return $this;
}
public final function setRenderer(DivinerRenderer $renderer) {
final public function setRenderer(DivinerRenderer $renderer) {
$renderer->setPublisher($this);
$this->renderer = $renderer;
return $this;
}
public final function getRenderer() {
final public function getRenderer() {
return $this->renderer;
}
public final function setConfig(array $config) {
final public function setConfig(array $config) {
$this->config = $config;
return $this;
}
public final function getConfig($key, $default = null) {
final public function getConfig($key, $default = null) {
return idx($this->config, $key, $default);
}
public final function getConfigurationData() {
final public function getConfigurationData() {
return $this->config;
}
public final function setAtomCache(DivinerAtomCache $cache) {
final public function setAtomCache(DivinerAtomCache $cache) {
$this->atomCache = $cache;
$graph_map = $this->atomCache->getGraphMap();
$this->atomGraphHashToNodeHashMap = array_flip($graph_map);
return $this;
}
protected final function getAtomFromGraphHash($graph_hash) {
final protected function getAtomFromGraphHash($graph_hash) {
if (empty($this->atomGraphHashToNodeHashMap[$graph_hash])) {
throw new Exception(pht("No such atom '%s'!", $graph_hash));
}
@ -54,7 +54,7 @@ abstract class DivinerPublisher {
$this->atomGraphHashToNodeHashMap[$graph_hash]);
}
protected final function getAtomFromNodeHash($node_hash) {
final protected function getAtomFromNodeHash($node_hash) {
if (empty($this->atomMap[$node_hash])) {
$dict = $this->atomCache->getAtom($node_hash);
$this->atomMap[$node_hash] = DivinerAtom::newFromDictionary($dict);
@ -62,7 +62,7 @@ abstract class DivinerPublisher {
return $this->atomMap[$node_hash];
}
protected final function getSimilarAtoms(DivinerAtom $atom) {
final protected function getSimilarAtoms(DivinerAtom $atom) {
if ($this->symbolReverseMap === null) {
$rmap = array();
$smap = $this->atomCache->getSymbolMap();
@ -94,7 +94,7 @@ abstract class DivinerPublisher {
* `f()`, we assign them an arbitrary (but fairly stable) order and publish
* them as `function/f/1/`, `function/f/2/`, etc., or similar.
*/
protected final function getAtomSimilarIndex(DivinerAtom $atom) {
final protected function getAtomSimilarIndex(DivinerAtom $atom) {
$atoms = $this->getSimilarAtoms($atom);
if (count($atoms) == 1) {
return 0;
@ -116,7 +116,7 @@ abstract class DivinerPublisher {
abstract protected function createDocumentsByHash(array $hashes);
abstract public function findAtomByRef(DivinerAtomRef $ref);
public final function publishAtoms(array $hashes) {
final public function publishAtoms(array $hashes) {
$existing = $this->loadAllPublishedHashes();
if ($this->dropCaches) {
@ -140,7 +140,7 @@ abstract class DivinerPublisher {
$this->createDocumentsByHash($created);
}
protected final function shouldGenerateDocumentForAtom(DivinerAtom $atom) {
final protected function shouldGenerateDocumentForAtom(DivinerAtom $atom) {
switch ($atom->getType()) {
case DivinerAtom::TYPE_METHOD:
case DivinerAtom::TYPE_FILE:

View file

@ -9,8 +9,8 @@ final class DivinerAtomQuery extends PhabricatorCursorPagedPolicyAwareQuery {
private $types;
private $contexts;
private $indexes;
private $includeUndocumentable;
private $includeGhosts;
private $isDocumentable;
private $isGhost;
private $nodeHashes;
private $titles;
private $nameContains;
@ -81,9 +81,9 @@ final class DivinerAtomQuery extends PhabricatorCursorPagedPolicyAwareQuery {
/**
* Include "ghosts", which are symbols which used to exist but do not exist
* currently (for example, a function which existed in an older version of
* the codebase but was deleted).
* Include or exclude "ghosts", which are symbols which used to exist but do
* not exist currently (for example, a function which existed in an older
* version of the codebase but was deleted).
*
* These symbols had PHIDs assigned to them, and may have other sorts of
* metadata that we don't want to lose (like comments or flags), so we don't
@ -92,14 +92,11 @@ final class DivinerAtomQuery extends PhabricatorCursorPagedPolicyAwareQuery {
* have been generated incorrectly by accident. In these cases, we can
* restore the original data.
*
* However, most callers are not interested in these symbols, so they are
* excluded by default. You can use this method to include them in results.
*
* @param bool True to include ghosts.
* @param bool
* @return this
*/
public function withIncludeGhosts($include) {
$this->includeGhosts = $include;
public function withGhosts($ghosts) {
$this->isGhost = $ghosts;
return $this;
}
@ -108,8 +105,8 @@ final class DivinerAtomQuery extends PhabricatorCursorPagedPolicyAwareQuery {
return $this;
}
public function withIncludeUndocumentable($include) {
$this->includeUndocumentable = $include;
public function withIsDocumentable($documentable) {
$this->isDocumentable = $documentable;
return $this;
}
@ -154,10 +151,6 @@ final class DivinerAtomQuery extends PhabricatorCursorPagedPolicyAwareQuery {
foreach ($atoms as $key => $atom) {
$data = idx($atom_data, $atom->getPHID());
if (!$data) {
unset($atoms[$key]);
continue;
}
$atom->attachAtom($data);
}
}
@ -173,6 +166,10 @@ final class DivinerAtomQuery extends PhabricatorCursorPagedPolicyAwareQuery {
$names = array();
foreach ($atoms as $atom) {
if (!$atom->getAtom()) {
continue;
}
foreach ($atom->getAtom()->getExtends() as $xref) {
$names[] = $xref->getName();
}
@ -192,10 +189,17 @@ final class DivinerAtomQuery extends PhabricatorCursorPagedPolicyAwareQuery {
}
foreach ($atoms as $atom) {
$alang = $atom->getAtom()->getLanguage();
$extends = array();
foreach ($atom->getAtom()->getExtends() as $xref) {
$atom_lang = null;
$atom_extends = array();
if ($atom->getAtom()) {
$atom_lang = $atom->getAtom()->getLanguage();
$atom_extends = $atom->getAtom()->getExtends();
}
$extends = array();
foreach ($atom_extends as $xref) {
// If there are no symbols of the matching name and type, we can't
// resolve this.
if (empty($xatoms[$xref->getName()][$xref->getType()])) {
@ -219,7 +223,7 @@ final class DivinerAtomQuery extends PhabricatorCursorPagedPolicyAwareQuery {
// classes can not implement JS classes.
$same_lang = array();
foreach ($maybe as $xatom) {
if ($xatom->getAtom()->getLanguage() == $alang) {
if ($xatom->getAtom()->getLanguage() == $atom_lang) {
$same_lang[] = $xatom;
}
}
@ -243,7 +247,6 @@ final class DivinerAtomQuery extends PhabricatorCursorPagedPolicyAwareQuery {
if ($child_hashes) {
$children = id(new DivinerAtomQuery())
->setViewer($this->getViewer())
->withIncludeUndocumentable(true)
->withNodeHashes($child_hashes)
->needAtoms($this->needAtoms)
->execute();
@ -346,16 +349,19 @@ final class DivinerAtomQuery extends PhabricatorCursorPagedPolicyAwareQuery {
$this->indexes);
}
if (!$this->includeUndocumentable) {
if ($this->isDocumentable !== null) {
$where[] = qsprintf(
$conn_r,
'isDocumentable = 1');
'isDocumentable = %d',
(int)$this->isDocumentable);
}
if (!$this->includeGhosts) {
$where[] = qsprintf(
$conn_r,
'graphHash IS NOT NULL');
if ($this->isGhost !== null) {
if ($this->isGhost) {
$where[] = qsprintf($conn_r, 'graphHash IS NULL');
} else {
$where[] = qsprintf($conn_r, 'graphHash IS NOT NULL');
}
}
if ($this->nodeHashes) {
@ -397,7 +403,13 @@ final class DivinerAtomQuery extends PhabricatorCursorPagedPolicyAwareQuery {
$hashes = array();
foreach ($symbols as $symbol) {
foreach ($symbol->getAtom()->getChildHashes() as $hash) {
$child_hashes = array();
if ($symbol->getAtom()) {
$child_hashes = $symbol->getAtom()->getChildHashes();
}
foreach ($child_hashes as $hash) {
$hashes[$hash] = $hash;
}
if ($recurse_up) {
@ -427,8 +439,14 @@ final class DivinerAtomQuery extends PhabricatorCursorPagedPolicyAwareQuery {
assert_instances_of($children, 'DivinerLiveSymbol');
foreach ($symbols as $symbol) {
$child_hashes = array();
$symbol_children = array();
foreach ($symbol->getAtom()->getChildHashes() as $hash) {
if ($symbol->getAtom()) {
$child_hashes = $symbol->getAtom()->getChildHashes();
}
foreach ($child_hashes as $hash) {
if (isset($children[$hash])) {
$symbol_children[] = $children[$hash];
}

View file

@ -0,0 +1,31 @@
<?php
final class DivinerAtomSearchIndexer extends PhabricatorSearchDocumentIndexer {
public function getIndexableObject() {
return new DivinerLiveSymbol();
}
protected function buildAbstractDocumentByPHID($phid) {
$atom = $this->loadDocumentByPHID($phid);
$book = $atom->getBook();
$doc = $this->newDocument($phid)
->setDocumentTitle($atom->getTitle())
->setDocumentCreated($book->getDateCreated())
->setDocumentModified($book->getDateModified());
$doc->addField(
PhabricatorSearchDocumentFieldType::FIELD_BODY,
$atom->getSummary());
$doc->addRelationship(
PhabricatorSearchRelationship::RELATIONSHIP_BOOK,
$atom->getBookPHID(),
DivinerBookPHIDType::TYPECONST,
$book->getDateCreated());
return $doc;
}
}

Some files were not shown because too many files have changed in this diff Show more