Page MenuHomestyx hydra

No OneTemporary

diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php
index c3a00d6f07..1135532206 100644
--- a/src/__phutil_library_map__.php
+++ b/src/__phutil_library_map__.php
@@ -1,1936 +1,1937 @@
<?php
/**
* This file is automatically generated. Use 'phutil_mapper.php' to rebuild it.
* @generated
*/
phutil_register_library_map(array(
'class' =>
array(
'Aphront304Response' => 'aphront/response/304',
'Aphront400Response' => 'aphront/response/400',
'Aphront403Response' => 'aphront/response/403',
'Aphront404Response' => 'aphront/response/404',
'AphrontAjaxResponse' => 'aphront/response/ajax',
'AphrontApplicationConfiguration' => 'aphront/applicationconfiguration',
'AphrontAttachedFileView' => 'view/control/attachedfile',
'AphrontCSRFException' => 'aphront/exception/csrf',
'AphrontCalendarEventView' => 'applications/calendar/view/event',
'AphrontCalendarMonthView' => 'applications/calendar/view/month',
'AphrontContextBarView' => 'view/layout/contextbar',
'AphrontController' => 'aphront/controller',
'AphrontCrumbsView' => 'view/layout/crumbs',
'AphrontDatabaseConnection' => 'storage/connection/base',
'AphrontDatabaseTransactionState' => 'storage/transaction',
'AphrontDefaultApplicationConfiguration' => 'aphront/default/configuration',
'AphrontDialogResponse' => 'aphront/response/dialog',
'AphrontDialogView' => 'view/dialog',
'AphrontErrorView' => 'view/form/error',
'AphrontException' => 'aphront/exception/base',
'AphrontFilePreviewView' => 'view/layout/filepreview',
'AphrontFileResponse' => 'aphront/response/file',
'AphrontFormCheckboxControl' => 'view/form/control/checkbox',
'AphrontFormControl' => 'view/form/control/base',
'AphrontFormDateControl' => 'view/form/control/date',
'AphrontFormDividerControl' => 'view/form/control/divider',
'AphrontFormDragAndDropUploadControl' => 'view/form/control/draganddropupload',
'AphrontFormFileControl' => 'view/form/control/file',
'AphrontFormInsetView' => 'view/form/inset',
'AphrontFormLayoutView' => 'view/form/layout',
'AphrontFormMarkupControl' => 'view/form/control/markup',
'AphrontFormPasswordControl' => 'view/form/control/password',
'AphrontFormPolicyControl' => 'view/form/control/policy',
'AphrontFormRadioButtonControl' => 'view/form/control/radio',
'AphrontFormRecaptchaControl' => 'view/form/control/recaptcha',
'AphrontFormSelectControl' => 'view/form/control/select',
'AphrontFormStaticControl' => 'view/form/control/static',
'AphrontFormSubmitControl' => 'view/form/control/submit',
'AphrontFormTextAreaControl' => 'view/form/control/textarea',
'AphrontFormTextControl' => 'view/form/control/text',
'AphrontFormToggleButtonsControl' => 'view/form/control/togglebuttons',
'AphrontFormTokenizerControl' => 'view/form/control/tokenizer',
'AphrontFormView' => 'view/form/base',
'AphrontHTTPSink' => 'aphront/sink/base',
'AphrontHTTPSinkTestCase' => 'aphront/sink/base/__tests__',
'AphrontHeadsupActionListView' => 'view/layout/headsup/actionlist',
'AphrontHeadsupActionView' => 'view/layout/headsup/action',
'AphrontHeadsupView' => 'view/layout/headsup/panel',
'AphrontIDPagerView' => 'view/control/idpager',
'AphrontIsolatedDatabaseConnection' => 'storage/connection/isolated',
'AphrontIsolatedDatabaseConnectionTestCase' => 'storage/connection/isolated/__tests__',
'AphrontIsolatedHTTPSink' => 'aphront/sink/test',
'AphrontJSONResponse' => 'aphront/response/json',
'AphrontJavelinView' => 'view/javelin-view',
'AphrontKeyboardShortcutsAvailableView' => 'view/widget/keyboardshortcuts',
'AphrontListFilterView' => 'view/layout/listfilter',
'AphrontMiniPanelView' => 'view/layout/minipanel',
'AphrontMoreView' => 'view/layout/more',
'AphrontMySQLDatabaseConnection' => 'storage/connection/mysql/mysql',
'AphrontMySQLDatabaseConnectionBase' => 'storage/connection/mysql/base',
'AphrontMySQLDatabaseConnectionTestCase' => 'storage/connection/mysql/__tests__',
'AphrontMySQLiDatabaseConnection' => 'storage/connection/mysql/mysqli',
'AphrontNullView' => 'view/null',
'AphrontPHPHTTPSink' => 'aphront/sink/php',
'AphrontPageView' => 'view/page/base',
'AphrontPagerView' => 'view/control/pager',
'AphrontPanelView' => 'view/layout/panel',
'AphrontPlainTextResponse' => 'aphront/response/plaintext',
'AphrontProxyResponse' => 'aphront/response/proxy',
'AphrontQueryAccessDeniedException' => 'storage/exception/accessdenied',
'AphrontQueryConnectionException' => 'storage/exception/connection',
'AphrontQueryConnectionLostException' => 'storage/exception/connectionlost',
'AphrontQueryCountException' => 'storage/exception/count',
'AphrontQueryDeadlockException' => 'storage/exception/deadlock',
'AphrontQueryDuplicateKeyException' => 'storage/exception/duplicatekey',
'AphrontQueryException' => 'storage/exception/base',
'AphrontQueryObjectMissingException' => 'storage/exception/objectmissing',
'AphrontQueryParameterException' => 'storage/exception/parameter',
'AphrontQueryRecoverableException' => 'storage/exception/recoverable',
'AphrontQuerySchemaException' => 'storage/exception/schema',
'AphrontRedirectException' => 'aphront/exception/redirect',
'AphrontRedirectResponse' => 'aphront/response/redirect',
'AphrontReloadResponse' => 'aphront/response/reload',
'AphrontRequest' => 'aphront/request',
'AphrontRequestFailureView' => 'view/page/failure',
'AphrontRequestTestCase' => 'aphront/request/__tests__',
'AphrontResponse' => 'aphront/response/base',
'AphrontScopedUnguardedWriteCapability' => 'aphront/writeguard/scopeguard',
'AphrontSideNavFilterView' => 'view/layout/sidenavfilter',
'AphrontSideNavView' => 'view/layout/sidenav',
'AphrontTableView' => 'view/control/table',
'AphrontTokenizerTemplateView' => 'view/control/tokenizer',
'AphrontTypeaheadTemplateView' => 'view/control/typeahead',
'AphrontURIMapper' => 'aphront/mapper',
'AphrontUsageException' => 'aphront/exception/usage',
'AphrontView' => 'view/base',
'AphrontWebpageResponse' => 'aphront/response/webpage',
'AphrontWriteGuard' => 'aphront/writeguard',
'CelerityAPI' => 'infrastructure/celerity/api',
'CelerityResourceController' => 'infrastructure/celerity/controller',
'CelerityResourceGraph' => 'infrastructure/celerity/graph',
'CelerityResourceMap' => 'infrastructure/celerity/map',
'CelerityResourceTransformer' => 'infrastructure/celerity/transformer',
'CelerityResourceTransformerTestCase' => 'infrastructure/celerity/transformer/__tests__',
'CelerityStaticResourceResponse' => 'infrastructure/celerity/response',
'ConduitAPIMethod' => 'applications/conduit/method/base',
'ConduitAPIRequest' => 'applications/conduit/protocol/request',
'ConduitAPIResponse' => 'applications/conduit/protocol/response',
'ConduitAPI_arcanist_Method' => 'applications/conduit/method/arcanist/base',
'ConduitAPI_arcanist_projectinfo_Method' => 'applications/conduit/method/arcanist/projectinfo',
'ConduitAPI_audit_Method' => 'applications/conduit/method/audit/base',
'ConduitAPI_audit_query_Method' => 'applications/conduit/method/audit/query',
'ConduitAPI_chatlog_Method' => 'applications/conduit/method/chatlog/base',
'ConduitAPI_chatlog_query_Method' => 'applications/conduit/method/chatlog/query',
'ConduitAPI_chatlog_record_Method' => 'applications/conduit/method/chatlog/record',
'ConduitAPI_conduit_connect_Method' => 'applications/conduit/method/conduit/connect',
'ConduitAPI_conduit_getcertificate_Method' => 'applications/conduit/method/conduit/getcertificate',
'ConduitAPI_conduit_ping_Method' => 'applications/conduit/method/conduit/ping',
'ConduitAPI_daemon_launched_Method' => 'applications/conduit/method/daemon/launched',
'ConduitAPI_daemon_log_Method' => 'applications/conduit/method/daemon/log',
'ConduitAPI_differential_close_Method' => 'applications/conduit/method/differential/close',
'ConduitAPI_differential_createcomment_Method' => 'applications/conduit/method/differential/createcomment',
'ConduitAPI_differential_creatediff_Method' => 'applications/conduit/method/differential/creatediff',
'ConduitAPI_differential_createrevision_Method' => 'applications/conduit/method/differential/createrevision',
'ConduitAPI_differential_find_Method' => 'applications/conduit/method/differential/find',
'ConduitAPI_differential_getalldiffs_Method' => 'applications/conduit/method/differential/getalldiffs',
'ConduitAPI_differential_getcommitmessage_Method' => 'applications/conduit/method/differential/getcommitmessage',
'ConduitAPI_differential_getcommitpaths_Method' => 'applications/conduit/method/differential/getcommitpaths',
'ConduitAPI_differential_getdiff_Method' => 'applications/conduit/method/differential/getdiff',
'ConduitAPI_differential_getrevision_Method' => 'applications/conduit/method/differential/getrevision',
'ConduitAPI_differential_getrevisioncomments_Method' => 'applications/conduit/method/differential/getrevisioncomments',
'ConduitAPI_differential_getrevisionfeedback_Method' => 'applications/conduit/method/differential/getrevisionfeedback',
'ConduitAPI_differential_markcommitted_Method' => 'applications/conduit/method/differential/markcommitted',
'ConduitAPI_differential_parsecommitmessage_Method' => 'applications/conduit/method/differential/parsecommitmessage',
'ConduitAPI_differential_query_Method' => 'applications/conduit/method/differential/query',
'ConduitAPI_differential_setdiffproperty_Method' => 'applications/conduit/method/differential/setdiffproperty',
'ConduitAPI_differential_updaterevision_Method' => 'applications/conduit/method/differential/updaterevision',
'ConduitAPI_differential_updatetaskrevisionassoc_Method' => 'applications/conduit/method/differential/updatetaskrevisionassoc',
'ConduitAPI_differential_updateunitresults_Method' => 'applications/conduit/method/differential/updateunitresults',
'ConduitAPI_diffusion_findsymbols_Method' => 'applications/conduit/method/diffusion/findsymbols',
'ConduitAPI_diffusion_getcommits_Method' => 'applications/conduit/method/diffusion/getcommits',
'ConduitAPI_diffusion_getrecentcommitsbypath_Method' => 'applications/conduit/method/diffusion/getrecentcommitsbypath',
'ConduitAPI_feed_publish_Method' => 'applications/conduit/method/feed/publish',
'ConduitAPI_feed_query_Method' => 'applications/conduit/method/feed/query',
'ConduitAPI_file_download_Method' => 'applications/conduit/method/file/download',
'ConduitAPI_file_info_Method' => 'applications/conduit/method/file/info',
'ConduitAPI_file_upload_Method' => 'applications/conduit/method/file/upload',
'ConduitAPI_flag_Method' => 'applications/conduit/method/flag/base',
'ConduitAPI_flag_query_Method' => 'applications/conduit/method/flag/query',
'ConduitAPI_macro_Method' => 'applications/conduit/method/macro/base',
'ConduitAPI_macro_query_Method' => 'applications/conduit/method/macro/query',
'ConduitAPI_maniphest_Method' => 'applications/conduit/method/maniphest/base',
'ConduitAPI_maniphest_createtask_Method' => 'applications/conduit/method/maniphest/createtask',
'ConduitAPI_maniphest_find_Method' => 'applications/conduit/method/maniphest/find',
'ConduitAPI_maniphest_gettasktransactions_Method' => 'applications/conduit/method/maniphest/gettasktransactions',
'ConduitAPI_maniphest_info_Method' => 'applications/conduit/method/maniphest/info',
'ConduitAPI_maniphest_update_Method' => 'applications/conduit/method/maniphest/update',
'ConduitAPI_owners_query_Method' => 'applications/conduit/method/owners/query',
'ConduitAPI_paste_Method' => 'applications/conduit/method/paste/base',
'ConduitAPI_paste_create_Method' => 'applications/conduit/method/paste/create',
'ConduitAPI_paste_info_Method' => 'applications/conduit/method/paste/info',
'ConduitAPI_path_getowners_Method' => 'applications/conduit/method/path/getowners',
'ConduitAPI_phid_Method' => 'applications/conduit/method/phid/base',
'ConduitAPI_phid_info_Method' => 'applications/conduit/method/phid/info',
'ConduitAPI_phid_query_Method' => 'applications/conduit/method/phid/query',
'ConduitAPI_phriction_Method' => 'applications/conduit/method/phriction/base',
'ConduitAPI_phriction_edit_Method' => 'applications/conduit/method/phriction/edit',
'ConduitAPI_phriction_history_Method' => 'applications/conduit/method/phriction/history',
'ConduitAPI_phriction_info_Method' => 'applications/conduit/method/phriction/info',
'ConduitAPI_project_Method' => 'applications/conduit/method/project/base',
'ConduitAPI_project_query_Method' => 'applications/conduit/method/project/query',
'ConduitAPI_remarkup_process_Method' => 'applications/conduit/method/remarkup/process',
'ConduitAPI_repository_Method' => 'applications/conduit/method/repository/base',
'ConduitAPI_repository_create_Method' => 'applications/conduit/method/repository/create',
'ConduitAPI_repository_query_Method' => 'applications/conduit/method/repository/query',
'ConduitAPI_slowvote_info_Method' => 'applications/conduit/method/slowvote/info',
'ConduitAPI_user_Method' => 'applications/conduit/method/user/base',
'ConduitAPI_user_addstatus_Method' => 'applications/conduit/method/user/addstatus',
'ConduitAPI_user_disable_Method' => 'applications/conduit/method/user/disable',
'ConduitAPI_user_find_Method' => 'applications/conduit/method/user/find',
'ConduitAPI_user_info_Method' => 'applications/conduit/method/user/info',
'ConduitAPI_user_query_Method' => 'applications/conduit/method/user/query',
'ConduitAPI_user_removestatus_Method' => 'applications/conduit/method/user/removestatus',
'ConduitAPI_user_whoami_Method' => 'applications/conduit/method/user/whoami',
'ConduitException' => 'applications/conduit/protocol/exception',
'DarkConsoleConfigPlugin' => 'aphront/console/plugin/config',
'DarkConsoleController' => 'aphront/console/controller',
'DarkConsoleCore' => 'aphront/console/core',
'DarkConsoleErrorLogPlugin' => 'aphront/console/plugin/errorlog',
'DarkConsoleErrorLogPluginAPI' => 'aphront/console/plugin/errorlog/api',
'DarkConsoleEventPlugin' => 'aphront/console/plugin/event',
'DarkConsoleEventPluginAPI' => 'aphront/console/plugin/event/api',
'DarkConsolePlugin' => 'aphront/console/plugin/base',
'DarkConsoleRequestPlugin' => 'aphront/console/plugin/request',
'DarkConsoleServicesPlugin' => 'aphront/console/plugin/services',
'DarkConsoleXHProfPlugin' => 'aphront/console/plugin/xhprof',
'DarkConsoleXHProfPluginAPI' => 'aphront/console/plugin/xhprof/api',
'DatabaseConfigurationProvider' => 'applications/base/storage/configuration/base',
'DefaultDatabaseConfigurationProvider' => 'applications/base/storage/configuration/default',
'DifferentialAction' => 'applications/differential/constants/action',
'DifferentialActionHasNoEffectException' => 'applications/differential/exception/noeffect',
'DifferentialAddCommentView' => 'applications/differential/view/addcomment',
'DifferentialAffectedPath' => 'applications/differential/storage/affectedpath',
'DifferentialApplyPatchFieldSpecification' => 'applications/differential/field/specification/applypatch',
'DifferentialArcanistProjectFieldSpecification' => 'applications/differential/field/specification/arcanistproject',
'DifferentialAuditorsFieldSpecification' => 'applications/differential/field/specification/auditors',
'DifferentialAuthorFieldSpecification' => 'applications/differential/field/specification/author',
'DifferentialAuxiliaryField' => 'applications/differential/storage/auxiliaryfield',
'DifferentialBlameRevisionFieldSpecification' => 'applications/differential/field/specification/blamerev',
'DifferentialBranchFieldSpecification' => 'applications/differential/field/specification/branch',
'DifferentialCCWelcomeMail' => 'applications/differential/mail/ccwelcome',
'DifferentialCCsFieldSpecification' => 'applications/differential/field/specification/ccs',
'DifferentialChangeType' => 'applications/differential/constants/changetype',
'DifferentialChangeset' => 'applications/differential/storage/changeset',
'DifferentialChangesetDetailView' => 'applications/differential/view/changesetdetailview',
'DifferentialChangesetListView' => 'applications/differential/view/changesetlistview',
'DifferentialChangesetParser' => 'applications/differential/parser/changeset',
'DifferentialChangesetViewController' => 'applications/differential/controller/changesetview',
'DifferentialComment' => 'applications/differential/storage/comment',
'DifferentialCommentEditor' => 'applications/differential/editor/comment',
'DifferentialCommentMail' => 'applications/differential/mail/comment',
'DifferentialCommentPreviewController' => 'applications/differential/controller/commentpreview',
'DifferentialCommentSaveController' => 'applications/differential/controller/commentsave',
'DifferentialCommitsFieldSpecification' => 'applications/differential/field/specification/commits',
'DifferentialController' => 'applications/differential/controller/base',
'DifferentialDAO' => 'applications/differential/storage/base',
'DifferentialDateCreatedFieldSpecification' => 'applications/differential/field/specification/datecreated',
'DifferentialDateModifiedFieldSpecification' => 'applications/differential/field/specification/datemodified',
'DifferentialDefaultFieldSelector' => 'applications/differential/field/selector/default',
'DifferentialDependenciesFieldSpecification' => 'applications/differential/field/specification/dependencies',
'DifferentialDiff' => 'applications/differential/storage/diff',
'DifferentialDiffContentMail' => 'applications/differential/mail/diffcontent',
'DifferentialDiffCreateController' => 'applications/differential/controller/diffcreate',
'DifferentialDiffProperty' => 'applications/differential/storage/diffproperty',
'DifferentialDiffTableOfContentsView' => 'applications/differential/view/difftableofcontents',
'DifferentialDiffViewController' => 'applications/differential/controller/diffview',
'DifferentialException' => 'applications/differential/exception/base',
'DifferentialExceptionMail' => 'applications/differential/mail/exception',
'DifferentialExportPatchFieldSpecification' => 'applications/differential/field/specification/exportpatch',
'DifferentialFieldDataNotAvailableException' => 'applications/differential/field/exception/notavailable',
'DifferentialFieldParseException' => 'applications/differential/field/exception/parse',
'DifferentialFieldSelector' => 'applications/differential/field/selector/base',
'DifferentialFieldSpecification' => 'applications/differential/field/specification/base',
'DifferentialFieldSpecificationIncompleteException' => 'applications/differential/field/exception/incomplete',
'DifferentialFieldValidationException' => 'applications/differential/field/exception/validation',
'DifferentialGitSVNIDFieldSpecification' => 'applications/differential/field/specification/gitsvnid',
'DifferentialHostFieldSpecification' => 'applications/differential/field/specification/host',
'DifferentialHunk' => 'applications/differential/storage/hunk',
'DifferentialInlineComment' => 'applications/differential/storage/inlinecomment',
'DifferentialInlineCommentEditController' => 'applications/differential/controller/inlinecommentedit',
'DifferentialInlineCommentEditView' => 'applications/differential/view/inlinecommentedit',
'DifferentialInlineCommentPreviewController' => 'applications/differential/controller/inlinecommentpreview',
'DifferentialInlineCommentView' => 'applications/differential/view/inlinecomment',
'DifferentialLinesFieldSpecification' => 'applications/differential/field/specification/lines',
'DifferentialLintFieldSpecification' => 'applications/differential/field/specification/lint',
'DifferentialLintStatus' => 'applications/differential/constants/lintstatus',
'DifferentialLocalCommitsView' => 'applications/differential/view/localcommits',
'DifferentialMail' => 'applications/differential/mail/base',
'DifferentialManiphestTasksFieldSpecification' => 'applications/differential/field/specification/maniphesttasks',
'DifferentialNewDiffMail' => 'applications/differential/mail/newdiff',
'DifferentialPathFieldSpecification' => 'applications/differential/field/specification/path',
'DifferentialPrimaryPaneView' => 'applications/differential/view/primarypane',
'DifferentialReplyHandler' => 'applications/differential/replyhandler',
'DifferentialResultsTableView' => 'applications/differential/view/resultstableview',
'DifferentialRevertPlanFieldSpecification' => 'applications/differential/field/specification/revertplan',
'DifferentialReviewRequestMail' => 'applications/differential/mail/reviewrequest',
'DifferentialReviewedByFieldSpecification' => 'applications/differential/field/specification/reviewedby',
'DifferentialReviewersFieldSpecification' => 'applications/differential/field/specification/reviewers',
'DifferentialRevision' => 'applications/differential/storage/revision',
'DifferentialRevisionCommentListView' => 'applications/differential/view/revisioncommentlist',
'DifferentialRevisionCommentView' => 'applications/differential/view/revisioncomment',
'DifferentialRevisionControlSystem' => 'applications/differential/constants/revisioncontrolsystem',
'DifferentialRevisionDetailRenderer' => 'applications/differential/controller/customrenderer',
'DifferentialRevisionDetailView' => 'applications/differential/view/revisiondetail',
'DifferentialRevisionEditController' => 'applications/differential/controller/revisionedit',
'DifferentialRevisionEditor' => 'applications/differential/editor/revision',
'DifferentialRevisionIDFieldParserTestCase' => 'applications/differential/field/specification/revisionid/__tests__',
'DifferentialRevisionIDFieldSpecification' => 'applications/differential/field/specification/revisionid',
'DifferentialRevisionListController' => 'applications/differential/controller/revisionlist',
'DifferentialRevisionListData' => 'applications/differential/data/revisionlist',
'DifferentialRevisionListView' => 'applications/differential/view/revisionlist',
'DifferentialRevisionQuery' => 'applications/differential/query/revision',
'DifferentialRevisionStatsController' => 'applications/differential/controller/revisionstats',
'DifferentialRevisionStatsView' => 'applications/differential/view/revisionstats',
'DifferentialRevisionStatusFieldSpecification' => 'applications/differential/field/specification/revisionstatus',
'DifferentialRevisionUpdateHistoryView' => 'applications/differential/view/revisionupdatehistory',
'DifferentialRevisionViewController' => 'applications/differential/controller/revisionview',
'DifferentialSubscribeController' => 'applications/differential/controller/subscribe',
'DifferentialSummaryFieldSpecification' => 'applications/differential/field/specification/summary',
'DifferentialTasksAttacher' => 'applications/differential/tasks',
'DifferentialTestPlanFieldSpecification' => 'applications/differential/field/specification/testplan',
'DifferentialTitleFieldSpecification' => 'applications/differential/field/specification/title',
'DifferentialUnitFieldSpecification' => 'applications/differential/field/specification/unit',
'DifferentialUnitStatus' => 'applications/differential/constants/unitstatus',
'DifferentialUnitTestResult' => 'applications/differential/constants/unittestresult',
'DiffusionBranchInformation' => 'applications/diffusion/data/branch',
'DiffusionBranchQuery' => 'applications/diffusion/query/branch/base',
'DiffusionBranchTableController' => 'applications/diffusion/controller/branchtable',
'DiffusionBranchTableView' => 'applications/diffusion/view/branchtable',
'DiffusionBrowseController' => 'applications/diffusion/controller/browse',
'DiffusionBrowseFileController' => 'applications/diffusion/controller/file',
'DiffusionBrowseQuery' => 'applications/diffusion/query/browse/base',
'DiffusionBrowseTableView' => 'applications/diffusion/view/browsetable',
'DiffusionChangeController' => 'applications/diffusion/controller/change',
'DiffusionCommentListView' => 'applications/diffusion/view/commentlist',
'DiffusionCommentView' => 'applications/diffusion/view/comment',
'DiffusionCommitChangeTableView' => 'applications/diffusion/view/commitchangetable',
'DiffusionCommitController' => 'applications/diffusion/controller/commit',
'DiffusionCommitParentsQuery' => 'applications/diffusion/query/parents/base',
'DiffusionCommitTagsQuery' => 'applications/diffusion/query/committags/base',
'DiffusionContainsQuery' => 'applications/diffusion/query/contains/base',
'DiffusionController' => 'applications/diffusion/controller/base',
'DiffusionDiffController' => 'applications/diffusion/controller/diff',
'DiffusionDiffQuery' => 'applications/diffusion/query/diff/base',
'DiffusionEmptyResultView' => 'applications/diffusion/view/emptyresult',
'DiffusionExternalController' => 'applications/diffusion/controller/external',
'DiffusionFileContent' => 'applications/diffusion/data/filecontent',
'DiffusionFileContentQuery' => 'applications/diffusion/query/filecontent/base',
'DiffusionGitBranchQuery' => 'applications/diffusion/query/branch/git',
'DiffusionGitBranchQueryTestCase' => 'applications/diffusion/query/branch/git/__tests__',
'DiffusionGitBrowseQuery' => 'applications/diffusion/query/browse/git',
'DiffusionGitCommitParentsQuery' => 'applications/diffusion/query/parents/git',
'DiffusionGitCommitTagsQuery' => 'applications/diffusion/query/committags/git',
'DiffusionGitContainsQuery' => 'applications/diffusion/query/contains/git',
'DiffusionGitDiffQuery' => 'applications/diffusion/query/diff/git',
'DiffusionGitFileContentQuery' => 'applications/diffusion/query/filecontent/git',
'DiffusionGitHistoryQuery' => 'applications/diffusion/query/history/git',
'DiffusionGitLastModifiedQuery' => 'applications/diffusion/query/lastmodified/git',
'DiffusionGitMergedCommitsQuery' => 'applications/diffusion/query/mergedcommits/git',
'DiffusionGitRawDiffQuery' => 'applications/diffusion/query/rawdiff/git',
'DiffusionGitRenameHistoryQuery' => 'applications/diffusion/query/renamehistory/git',
'DiffusionGitRequest' => 'applications/diffusion/request/git',
'DiffusionGitTagListQuery' => 'applications/diffusion/query/taglist/git',
'DiffusionHistoryController' => 'applications/diffusion/controller/history',
'DiffusionHistoryQuery' => 'applications/diffusion/query/history/base',
'DiffusionHistoryTableView' => 'applications/diffusion/view/historytable',
'DiffusionHomeController' => 'applications/diffusion/controller/home',
'DiffusionInlineCommentController' => 'applications/diffusion/controller/inline',
'DiffusionLastModifiedController' => 'applications/diffusion/controller/lastmodified',
'DiffusionLastModifiedQuery' => 'applications/diffusion/query/lastmodified/base',
'DiffusionMercurialBranchQuery' => 'applications/diffusion/query/branch/mercurial',
'DiffusionMercurialBrowseQuery' => 'applications/diffusion/query/browse/mercurial',
'DiffusionMercurialCommitParentsQuery' => 'applications/diffusion/query/parents/mercurial',
'DiffusionMercurialCommitTagsQuery' => 'applications/diffusion/query/committags/mercurial',
'DiffusionMercurialContainsQuery' => 'applications/diffusion/query/contains/mercurial',
'DiffusionMercurialDiffQuery' => 'applications/diffusion/query/diff/mercurial',
'DiffusionMercurialFileContentQuery' => 'applications/diffusion/query/filecontent/mercurial',
'DiffusionMercurialHistoryQuery' => 'applications/diffusion/query/history/mercurial',
'DiffusionMercurialLastModifiedQuery' => 'applications/diffusion/query/lastmodified/mercurial',
'DiffusionMercurialMergedCommitsQuery' => 'applications/diffusion/query/mergedcommits/mercurial',
'DiffusionMercurialRawDiffQuery' => 'applications/diffusion/query/rawdiff/mercurial',
'DiffusionMercurialRenameHistoryQuery' => 'applications/diffusion/query/renamehistory/mercurial',
'DiffusionMercurialRequest' => 'applications/diffusion/request/mercurial',
'DiffusionMercurialTagListQuery' => 'applications/diffusion/query/taglist/mercurial',
'DiffusionMergedCommitsQuery' => 'applications/diffusion/query/mergedcommits/base',
'DiffusionPathChange' => 'applications/diffusion/data/pathchange',
'DiffusionPathChangeQuery' => 'applications/diffusion/query/pathchange/base',
'DiffusionPathCompleteController' => 'applications/diffusion/controller/pathcomplete',
'DiffusionPathIDQuery' => 'applications/diffusion/query/pathid/base',
'DiffusionPathQuery' => 'applications/diffusion/query/path',
'DiffusionPathQueryTestCase' => 'applications/diffusion/query/pathid/base/__tests__',
'DiffusionPathValidateController' => 'applications/diffusion/controller/pathvalidate',
'DiffusionQuery' => 'applications/diffusion/query/base',
'DiffusionRawDiffQuery' => 'applications/diffusion/query/rawdiff/base',
'DiffusionRenameHistoryQuery' => 'applications/diffusion/query/renamehistory/base',
'DiffusionRepositoryController' => 'applications/diffusion/controller/repository',
'DiffusionRepositoryPath' => 'applications/diffusion/data/repositorypath',
'DiffusionRepositoryTag' => 'applications/diffusion/tag',
'DiffusionRequest' => 'applications/diffusion/request/base',
'DiffusionSetupException' => 'applications/diffusion/exception/setup',
'DiffusionSvnBrowseQuery' => 'applications/diffusion/query/browse/svn',
'DiffusionSvnCommitParentsQuery' => 'applications/diffusion/query/parents/svn',
'DiffusionSvnCommitTagsQuery' => 'applications/diffusion/query/committags/svn',
'DiffusionSvnContainsQuery' => 'applications/diffusion/query/contains/svn',
'DiffusionSvnDiffQuery' => 'applications/diffusion/query/diff/svn',
'DiffusionSvnFileContentQuery' => 'applications/diffusion/query/filecontent/svn',
'DiffusionSvnHistoryQuery' => 'applications/diffusion/query/history/svn',
'DiffusionSvnLastModifiedQuery' => 'applications/diffusion/query/lastmodified/svn',
'DiffusionSvnMergedCommitsQuery' => 'applications/diffusion/query/mergedcommits/svn',
'DiffusionSvnRawDiffQuery' => 'applications/diffusion/query/rawdiff/svn',
'DiffusionSvnRenameHistoryQuery' => 'applications/diffusion/query/renamehistory/svn',
'DiffusionSvnRequest' => 'applications/diffusion/request/svn',
'DiffusionSvnTagListQuery' => 'applications/diffusion/query/taglist/svn',
'DiffusionSymbolController' => 'applications/diffusion/controller/symbol',
'DiffusionSymbolQuery' => 'applications/diffusion/query/symbol',
'DiffusionTagListController' => 'applications/diffusion/controller/taglist',
'DiffusionTagListQuery' => 'applications/diffusion/query/taglist/base',
'DiffusionTagListView' => 'applications/diffusion/view/taglist',
'DiffusionURITestCase' => 'applications/diffusion/request/base/__tests__',
'DiffusionView' => 'applications/diffusion/view/base',
'DrydockAllocator' => 'applications/drydock/allocator/resource',
'DrydockAllocatorWorker' => 'applications/drydock/allocator/worker',
'DrydockApacheWebrootBlueprint' => 'applications/drydock/blueprint/webroot/apache',
'DrydockApacheWebrootInterface' => 'applications/drydock/interface/webroot/apache',
'DrydockBlueprint' => 'applications/drydock/blueprint/base',
'DrydockCommandInterface' => 'applications/drydock/interface/command/base',
'DrydockConstants' => 'applications/drydock/constants/base',
'DrydockController' => 'applications/drydock/controller/base',
'DrydockDAO' => 'applications/drydock/storage/base',
'DrydockEC2HostBlueprint' => 'applications/drydock/blueprint/ec2host',
'DrydockInterface' => 'applications/drydock/interface/base',
'DrydockLease' => 'applications/drydock/storage/lease',
'DrydockLeaseListController' => 'applications/drydock/controller/leaselist',
'DrydockLeaseStatus' => 'applications/drydock/constants/leasestatus',
'DrydockLocalCommandInterface' => 'applications/drydock/interface/command/local',
'DrydockLocalHostBlueprint' => 'applications/drydock/blueprint/localhost',
'DrydockLog' => 'applications/drydock/storage/log',
'DrydockLogController' => 'applications/drydock/controller/log',
'DrydockLogQuery' => 'applications/drydock/query/log',
'DrydockPhabricatorApplicationBlueprint' => 'applications/drydock/blueprint/application/phabricator',
'DrydockRemoteHostBlueprint' => 'applications/drydock/blueprint/remotehost',
'DrydockResource' => 'applications/drydock/storage/resource',
'DrydockResourceAllocateController' => 'applications/drydock/controller/resourceallocate',
'DrydockResourceListController' => 'applications/drydock/controller/resourcelist',
'DrydockResourceStatus' => 'applications/drydock/constants/resourcestatus',
'DrydockSSHCommandInterface' => 'applications/drydock/interface/command/ssh',
'DrydockWebrootInterface' => 'applications/drydock/interface/webroot/base',
'HarbormasterDAO' => 'applications/harbormaster/storage/base',
'HarbormasterScratchTable' => 'applications/harbormaster/storage/scratchtable',
'HeraldAction' => 'applications/herald/storage/action',
'HeraldActionConfig' => 'applications/herald/config/action',
'HeraldApplyTranscript' => 'applications/herald/storage/transcript/apply',
'HeraldCommitAdapter' => 'applications/herald/adapter/commit',
'HeraldCondition' => 'applications/herald/storage/condition',
'HeraldConditionConfig' => 'applications/herald/config/condition',
'HeraldConditionTranscript' => 'applications/herald/storage/transcript/condition',
'HeraldContentTypeConfig' => 'applications/herald/config/contenttype',
'HeraldController' => 'applications/herald/controller/base',
'HeraldDAO' => 'applications/herald/storage/base',
'HeraldDeleteController' => 'applications/herald/controller/delete',
'HeraldDifferentialRevisionAdapter' => 'applications/herald/adapter/differential',
'HeraldDryRunAdapter' => 'applications/herald/adapter/dryrun',
'HeraldEditLogQuery' => 'applications/herald/query/log',
'HeraldEffect' => 'applications/herald/engine/effect',
'HeraldEngine' => 'applications/herald/engine/engine',
'HeraldFieldConfig' => 'applications/herald/config/field',
'HeraldHomeController' => 'applications/herald/controller/home',
'HeraldInvalidConditionException' => 'applications/herald/engine/engine/exception',
'HeraldInvalidFieldException' => 'applications/herald/engine/engine/exception',
'HeraldNewController' => 'applications/herald/controller/new',
'HeraldObjectAdapter' => 'applications/herald/adapter/base',
'HeraldObjectTranscript' => 'applications/herald/storage/transcript/object',
'HeraldRecursiveConditionsException' => 'applications/herald/engine/engine/exception',
'HeraldRepetitionPolicyConfig' => 'applications/herald/config/repetitionpolicy',
'HeraldRule' => 'applications/herald/storage/rule',
'HeraldRuleController' => 'applications/herald/controller/rule',
'HeraldRuleEdit' => 'applications/herald/storage/edithistory',
'HeraldRuleEditHistoryController' => 'applications/herald/controller/edithistory',
'HeraldRuleEditHistoryView' => 'applications/herald/view/edithistory',
'HeraldRuleListView' => 'applications/herald/view/rulelist',
'HeraldRuleQuery' => 'applications/herald/query/rule',
'HeraldRuleTranscript' => 'applications/herald/storage/transcript/rule',
'HeraldRuleTypeConfig' => 'applications/herald/config/ruletype',
'HeraldTestConsoleController' => 'applications/herald/controller/test',
'HeraldTranscript' => 'applications/herald/storage/transcript/base',
'HeraldTranscriptController' => 'applications/herald/controller/transcript',
'HeraldTranscriptListController' => 'applications/herald/controller/transcriptlist',
'HeraldValueTypeConfig' => 'applications/herald/config/valuetype',
'Javelin' => 'infrastructure/javelin/api',
'JavelinReactorExample' => 'applications/uiexample/examples/reactor',
'JavelinViewExample' => 'applications/uiexample/examples/client',
'JavelinViewExampleServerView' => 'applications/uiexample/examples/client',
'LiskDAO' => 'storage/lisk/dao',
+ 'LiskDAOSet' => 'storage/lisk/dao',
'LiskEphemeralObjectException' => 'storage/lisk/dao',
'LiskFixtureTestCase' => 'storage/lisk/dao/__tests__',
'LiskIsolationTestCase' => 'storage/lisk/dao/__tests__',
'LiskIsolationTestDAO' => 'storage/lisk/dao/__tests__',
'LiskIsolationTestDAOException' => 'storage/lisk/dao/__tests__',
'ManiphestAction' => 'applications/maniphest/constants/action',
'ManiphestAuxiliaryFieldDefaultSpecification' => 'applications/maniphest/auxiliaryfield/default',
'ManiphestAuxiliaryFieldSpecification' => 'applications/maniphest/auxiliaryfield/base',
'ManiphestAuxiliaryFieldTypeException' => 'applications/maniphest/auxiliaryfield/typeexception',
'ManiphestAuxiliaryFieldValidationException' => 'applications/maniphest/auxiliaryfield/validationexception',
'ManiphestBatchEditController' => 'applications/maniphest/controller/batch',
'ManiphestConstants' => 'applications/maniphest/constants/base',
'ManiphestController' => 'applications/maniphest/controller/base',
'ManiphestDAO' => 'applications/maniphest/storage/base',
'ManiphestDefaultTaskExtensions' => 'applications/maniphest/extensions/task',
'ManiphestExportController' => 'applications/maniphest/controller/export',
'ManiphestReplyHandler' => 'applications/maniphest/replyhandler',
'ManiphestReportController' => 'applications/maniphest/controller/report',
'ManiphestSavedQuery' => 'applications/maniphest/storage/savedquery',
'ManiphestSavedQueryDeleteController' => 'applications/maniphest/controller/savedquerydelete',
'ManiphestSavedQueryEditController' => 'applications/maniphest/controller/savedqueryedit',
'ManiphestSavedQueryListController' => 'applications/maniphest/controller/savedquerylist',
'ManiphestSubpriorityController' => 'applications/maniphest/controller/subpriority',
'ManiphestTask' => 'applications/maniphest/storage/task',
'ManiphestTaskAuxiliaryStorage' => 'applications/maniphest/storage/auxiliary',
'ManiphestTaskDescriptionChangeController' => 'applications/maniphest/controller/descriptionchange',
'ManiphestTaskDescriptionPreviewController' => 'applications/maniphest/controller/descriptionpreview',
'ManiphestTaskDetailController' => 'applications/maniphest/controller/taskdetail',
'ManiphestTaskEditController' => 'applications/maniphest/controller/taskedit',
'ManiphestTaskExtensions' => 'applications/maniphest/extensions/base',
'ManiphestTaskListController' => 'applications/maniphest/controller/tasklist',
'ManiphestTaskListView' => 'applications/maniphest/view/tasklist',
'ManiphestTaskOwner' => 'applications/maniphest/constants/owner',
'ManiphestTaskPriority' => 'applications/maniphest/constants/priority',
'ManiphestTaskProject' => 'applications/maniphest/storage/taskproject',
'ManiphestTaskProjectsView' => 'applications/maniphest/view/taskprojects',
'ManiphestTaskQuery' => 'applications/maniphest/query',
'ManiphestTaskStatus' => 'applications/maniphest/constants/status',
'ManiphestTaskSubscriber' => 'applications/maniphest/storage/subscriber',
'ManiphestTaskSummaryView' => 'applications/maniphest/view/tasksummary',
'ManiphestTransaction' => 'applications/maniphest/storage/transaction',
'ManiphestTransactionDetailView' => 'applications/maniphest/view/transactiondetail',
'ManiphestTransactionEditor' => 'applications/maniphest/editor/transaction',
'ManiphestTransactionListView' => 'applications/maniphest/view/transactionlist',
'ManiphestTransactionPreviewController' => 'applications/maniphest/controller/transactionpreview',
'ManiphestTransactionSaveController' => 'applications/maniphest/controller/transactionsave',
'ManiphestTransactionType' => 'applications/maniphest/constants/transactiontype',
'ManiphestView' => 'applications/maniphest/view/base',
'MetaMTAConstants' => 'applications/metamta/constants/base',
'MetaMTANotificationType' => 'applications/metamta/constants/notificationtype',
'OwnersPackageReplyHandler' => 'applications/owners/replyhandler',
'PackageCreateMail' => 'applications/owners/mail/create',
'PackageDeleteMail' => 'applications/owners/mail/delete',
'PackageMail' => 'applications/owners/mail/base',
'PackageModifyMail' => 'applications/owners/mail/modify',
'Phabricator404Controller' => 'applications/base/controller/404',
'PhabricatorAccessLog' => 'infrastructure/accesslog',
'PhabricatorAphlictTestPageController' => 'applications/notifications/controller/test',
'PhabricatorAuditActionConstants' => 'applications/audit/constants/action',
'PhabricatorAuditAddCommentController' => 'applications/audit/controller/addcomment',
'PhabricatorAuditComment' => 'applications/audit/storage/auditcomment',
'PhabricatorAuditCommentEditor' => 'applications/audit/editor/comment',
'PhabricatorAuditCommitListView' => 'applications/audit/view/commitlist',
'PhabricatorAuditCommitQuery' => 'applications/audit/query/commit',
'PhabricatorAuditCommitStatusConstants' => 'applications/audit/constants/commitstatus',
'PhabricatorAuditController' => 'applications/audit/controller/base',
'PhabricatorAuditDAO' => 'applications/audit/storage/base',
'PhabricatorAuditInlineComment' => 'applications/audit/storage/inlinecommment',
'PhabricatorAuditListController' => 'applications/audit/controller/list',
'PhabricatorAuditListView' => 'applications/audit/view/list',
'PhabricatorAuditPreviewController' => 'applications/audit/controller/preview',
'PhabricatorAuditQuery' => 'applications/audit/query/audit',
'PhabricatorAuditReplyHandler' => 'applications/audit/replyhandler',
'PhabricatorAuditStatusConstants' => 'applications/audit/constants/status',
'PhabricatorAuthController' => 'applications/auth/controller/base',
'PhabricatorBuiltinPatchList' => 'infrastructure/setup/sql/phabricator',
'PhabricatorCalendarBrowseController' => 'applications/calendar/controller/browse',
'PhabricatorCalendarController' => 'applications/calendar/controller/base',
'PhabricatorCalendarDAO' => 'applications/calendar/storage/base',
'PhabricatorCalendarHoliday' => 'applications/calendar/storage/holiday',
'PhabricatorCalendarHolidayTestCase' => 'applications/calendar/storage/holiday/__tests__',
'PhabricatorChangesetResponse' => 'infrastructure/diff/response',
'PhabricatorChatLogChannelListController' => 'applications/chatlog/controller/channellist',
'PhabricatorChatLogChannelLogController' => 'applications/chatlog/controller/channellog',
'PhabricatorChatLogConstants' => 'applications/chatlog/constants/base',
'PhabricatorChatLogController' => 'applications/chatlog/controller/base',
'PhabricatorChatLogDAO' => 'applications/chatlog/storage/base',
'PhabricatorChatLogEvent' => 'applications/chatlog/storage/event',
'PhabricatorChatLogEventType' => 'applications/chatlog/constants/eventtype',
'PhabricatorChatLogQuery' => 'applications/chatlog/query',
'PhabricatorConduitAPIController' => 'applications/conduit/controller/api',
'PhabricatorConduitCertificateToken' => 'applications/conduit/storage/token',
'PhabricatorConduitConnectionLog' => 'applications/conduit/storage/connectionlog',
'PhabricatorConduitConsoleController' => 'applications/conduit/controller/console',
'PhabricatorConduitController' => 'applications/conduit/controller/base',
'PhabricatorConduitDAO' => 'applications/conduit/storage/base',
'PhabricatorConduitListController' => 'applications/conduit/controller/list',
'PhabricatorConduitLogController' => 'applications/conduit/controller/log',
'PhabricatorConduitMethodCallLog' => 'applications/conduit/storage/methodcalllog',
'PhabricatorConduitTokenController' => 'applications/conduit/controller/token',
'PhabricatorContentSource' => 'applications/metamta/contentsource/source',
'PhabricatorContentSourceView' => 'applications/metamta/contentsource/view',
'PhabricatorController' => 'applications/base/controller/base',
'PhabricatorCountdownController' => 'applications/countdown/controller/base',
'PhabricatorCountdownDAO' => 'applications/countdown/storage/base',
'PhabricatorCountdownDeleteController' => 'applications/countdown/controller/delete',
'PhabricatorCountdownEditController' => 'applications/countdown/controller/edit',
'PhabricatorCountdownListController' => 'applications/countdown/controller/list',
'PhabricatorCountdownViewController' => 'applications/countdown/controller/view',
'PhabricatorDaemon' => 'infrastructure/daemon/base',
'PhabricatorDaemonCombinedLogController' => 'applications/daemon/controller/combined',
'PhabricatorDaemonConsoleController' => 'applications/daemon/controller/console',
'PhabricatorDaemonControl' => 'infrastructure/daemon/control',
'PhabricatorDaemonController' => 'applications/daemon/controller/base',
'PhabricatorDaemonDAO' => 'infrastructure/daemon/storage/base',
'PhabricatorDaemonLog' => 'infrastructure/daemon/storage/log',
'PhabricatorDaemonLogEvent' => 'infrastructure/daemon/storage/event',
'PhabricatorDaemonLogEventsView' => 'applications/daemon/view/daemonlogevents',
'PhabricatorDaemonLogListController' => 'applications/daemon/controller/loglist',
'PhabricatorDaemonLogListView' => 'applications/daemon/view/daemonloglist',
'PhabricatorDaemonLogViewController' => 'applications/daemon/controller/logview',
'PhabricatorDaemonReference' => 'infrastructure/daemon/control/reference',
'PhabricatorDaemonTimelineConsoleController' => 'applications/daemon/controller/timeline',
'PhabricatorDaemonTimelineEventController' => 'applications/daemon/controller/timelineevent',
'PhabricatorDefaultFileStorageEngineSelector' => 'applications/files/engineselector/default',
'PhabricatorDefaultSearchEngineSelector' => 'applications/search/selector/default',
'PhabricatorDifferenceEngine' => 'infrastructure/diff/engine',
'PhabricatorDirectoryController' => 'applications/directory/controller/base',
'PhabricatorDirectoryMainController' => 'applications/directory/controller/main',
'PhabricatorDisabledUserController' => 'applications/auth/controller/disabled',
'PhabricatorDraft' => 'applications/draft/storage/draft',
'PhabricatorDraftDAO' => 'applications/draft/storage/base',
'PhabricatorEdgeConfig' => 'infrastructure/edges/constants/config',
'PhabricatorEdgeConstants' => 'infrastructure/edges/constants/base',
'PhabricatorEdgeEditor' => 'infrastructure/edges/editor/edge',
'PhabricatorEdgeQuery' => 'infrastructure/edges/query/edge',
'PhabricatorEmailLoginController' => 'applications/auth/controller/email',
'PhabricatorEmailTokenController' => 'applications/auth/controller/emailtoken',
'PhabricatorEmailVerificationController' => 'applications/people/controller/emailverification',
'PhabricatorEnv' => 'infrastructure/env',
'PhabricatorEnvTestCase' => 'infrastructure/env/__tests__',
'PhabricatorErrorExample' => 'applications/uiexample/examples/error',
'PhabricatorEvent' => 'infrastructure/events/event',
'PhabricatorEventEngine' => 'infrastructure/events/engine',
'PhabricatorEventType' => 'infrastructure/events/constant/type',
'PhabricatorFeedBuilder' => 'applications/feed/builder/feed',
'PhabricatorFeedConstants' => 'applications/feed/constants/base',
'PhabricatorFeedController' => 'applications/feed/controller/base',
'PhabricatorFeedDAO' => 'applications/feed/storage/base',
'PhabricatorFeedPublicStreamController' => 'applications/feed/controller/publicstream',
'PhabricatorFeedQuery' => 'applications/feed/query',
'PhabricatorFeedStory' => 'applications/feed/story/base',
'PhabricatorFeedStoryAudit' => 'applications/feed/story/audit',
'PhabricatorFeedStoryData' => 'applications/feed/storage/story',
'PhabricatorFeedStoryDifferential' => 'applications/feed/story/differential',
'PhabricatorFeedStoryManiphest' => 'applications/feed/story/maniphest',
'PhabricatorFeedStoryPhriction' => 'applications/feed/story/phriction',
'PhabricatorFeedStoryProject' => 'applications/feed/story/project',
'PhabricatorFeedStoryPublisher' => 'applications/feed/publisher',
'PhabricatorFeedStoryReference' => 'applications/feed/storage/storyreference',
'PhabricatorFeedStoryStatus' => 'applications/feed/story/status',
'PhabricatorFeedStoryTypeConstants' => 'applications/feed/constants/story',
'PhabricatorFeedStoryUnknown' => 'applications/feed/story/unknown',
'PhabricatorFeedStoryView' => 'applications/feed/view/story',
'PhabricatorFeedView' => 'applications/feed/view/base',
'PhabricatorFile' => 'applications/files/storage/file',
'PhabricatorFileController' => 'applications/files/controller/base',
'PhabricatorFileDAO' => 'applications/files/storage/base',
'PhabricatorFileDataController' => 'applications/files/controller/data',
'PhabricatorFileDeleteController' => 'applications/files/controller/delete',
'PhabricatorFileDropUploadController' => 'applications/files/controller/dropupload',
'PhabricatorFileImageMacro' => 'applications/files/storage/imagemacro',
'PhabricatorFileInfoController' => 'applications/files/controller/info',
'PhabricatorFileListController' => 'applications/files/controller/list',
'PhabricatorFileMacroDeleteController' => 'applications/files/controller/macrodelete',
'PhabricatorFileMacroEditController' => 'applications/files/controller/macroedit',
'PhabricatorFileMacroListController' => 'applications/files/controller/macrolist',
'PhabricatorFileProxyController' => 'applications/files/controller/proxy',
'PhabricatorFileProxyImage' => 'applications/files/storage/proxyimage',
'PhabricatorFileShortcutController' => 'applications/files/controller/shortcut',
'PhabricatorFileSideNavView' => 'applications/files/view/sidenav',
'PhabricatorFileStorageBlob' => 'applications/files/storage/storageblob',
'PhabricatorFileStorageConfigurationException' => 'applications/files/exception/configuration',
'PhabricatorFileStorageEngine' => 'applications/files/engine/base',
'PhabricatorFileStorageEngineSelector' => 'applications/files/engineselector/base',
'PhabricatorFileTransformController' => 'applications/files/controller/transform',
'PhabricatorFileUploadController' => 'applications/files/controller/upload',
'PhabricatorFileUploadException' => 'applications/files/exception/upload',
'PhabricatorFileUploadView' => 'applications/files/view/upload',
'PhabricatorFlag' => 'applications/flag/storage/flag',
'PhabricatorFlagColor' => 'applications/flag/constants/color',
'PhabricatorFlagConstants' => 'applications/flag/constants/base',
'PhabricatorFlagController' => 'applications/flag/controller/base',
'PhabricatorFlagDAO' => 'applications/flag/storage/base',
'PhabricatorFlagDeleteController' => 'applications/flag/controller/delete',
'PhabricatorFlagEditController' => 'applications/flag/controller/edit',
'PhabricatorFlagListController' => 'applications/flag/controller/list',
'PhabricatorFlagListView' => 'applications/flag/view/list',
'PhabricatorFlagQuery' => 'applications/flag/query/flag',
'PhabricatorFormExample' => 'applications/uiexample/examples/form',
'PhabricatorGarbageCollectorDaemon' => 'infrastructure/daemon/garbagecollector',
'PhabricatorGoodForNothingWorker' => 'infrastructure/daemon/workers/worker/goodfornothing',
'PhabricatorHandleObjectSelectorDataView' => 'applications/phid/handle/view/selector',
'PhabricatorHash' => 'infrastructure/util/hash',
'PhabricatorHelpController' => 'applications/help/controller/base',
'PhabricatorHelpKeyboardShortcutController' => 'applications/help/controller/keyboardshortcut',
'PhabricatorIDPagedPolicyQuery' => 'infrastructure/query/policy/idpaged',
'PhabricatorIRCBot' => 'infrastructure/daemon/irc/bot',
'PhabricatorIRCDifferentialNotificationHandler' => 'infrastructure/daemon/irc/handler/differentialnotification',
'PhabricatorIRCHandler' => 'infrastructure/daemon/irc/handler/base',
'PhabricatorIRCLogHandler' => 'infrastructure/daemon/irc/handler/log',
'PhabricatorIRCMacroHandler' => 'infrastructure/daemon/irc/handler/macro',
'PhabricatorIRCMessage' => 'infrastructure/daemon/irc/message',
'PhabricatorIRCObjectNameHandler' => 'infrastructure/daemon/irc/handler/objectname',
'PhabricatorIRCProtocolHandler' => 'infrastructure/daemon/irc/handler/protocol',
'PhabricatorIRCWhatsNewHandler' => 'infrastructure/daemon/irc/handler/whatsnew',
'PhabricatorImageTransformer' => 'applications/files/transform',
'PhabricatorInfrastructureTestCase' => 'infrastructure/__tests__',
'PhabricatorInlineCommentController' => 'infrastructure/diff/controller',
'PhabricatorInlineCommentInterface' => 'infrastructure/diff/interface/inline',
'PhabricatorInlineSummaryView' => 'infrastructure/diff/view/inline',
'PhabricatorJavelinLinter' => 'infrastructure/lint/linter/javelin',
'PhabricatorJumpNavHandler' => 'applications/search/engine/jumpnav',
'PhabricatorLintEngine' => 'infrastructure/lint/engine',
'PhabricatorLiskDAO' => 'applications/base/storage/lisk',
'PhabricatorLocalDiskFileStorageEngine' => 'applications/files/engine/localdisk',
'PhabricatorLocalTimeTestCase' => 'view/utils/__tests__',
'PhabricatorLoginController' => 'applications/auth/controller/login',
'PhabricatorLoginValidateController' => 'applications/auth/controller/validate',
'PhabricatorLogoutController' => 'applications/auth/controller/logout',
'PhabricatorMailImplementationAdapter' => 'applications/metamta/adapter/base',
'PhabricatorMailImplementationAmazonSESAdapter' => 'applications/metamta/adapter/amazonses',
'PhabricatorMailImplementationPHPMailerLiteAdapter' => 'applications/metamta/adapter/phpmailerlite',
'PhabricatorMailImplementationSendGridAdapter' => 'applications/metamta/adapter/sendgrid',
'PhabricatorMailImplementationTestAdapter' => 'applications/metamta/adapter/test',
'PhabricatorMailReplyHandler' => 'applications/metamta/replyhandler/base',
'PhabricatorMarkupEngine' => 'applications/markup/engine',
'PhabricatorMercurialGraphStream' => 'applications/repository/daemon/pulllocal',
'PhabricatorMetaMTAAttachment' => 'applications/metamta/storage/mail',
'PhabricatorMetaMTAController' => 'applications/metamta/controller/base',
'PhabricatorMetaMTADAO' => 'applications/metamta/storage/base',
'PhabricatorMetaMTAEmailBodyParser' => 'applications/metamta/parser',
'PhabricatorMetaMTAEmailBodyParserTestCase' => 'applications/metamta/parser/__tests__',
'PhabricatorMetaMTAListController' => 'applications/metamta/controller/list',
'PhabricatorMetaMTAMail' => 'applications/metamta/storage/mail',
'PhabricatorMetaMTAMailTestCase' => 'applications/metamta/storage/mail/__tests__',
'PhabricatorMetaMTAMailingList' => 'applications/metamta/storage/mailinglist',
'PhabricatorMetaMTAMailingListEditController' => 'applications/metamta/controller/mailinglistedit',
'PhabricatorMetaMTAMailingListsController' => 'applications/metamta/controller/mailinglists',
'PhabricatorMetaMTAReceiveController' => 'applications/metamta/controller/receive',
'PhabricatorMetaMTAReceivedListController' => 'applications/metamta/controller/receivedlist',
'PhabricatorMetaMTAReceivedMail' => 'applications/metamta/storage/receivedmail',
'PhabricatorMetaMTASendController' => 'applications/metamta/controller/send',
'PhabricatorMetaMTASendGridReceiveController' => 'applications/metamta/controller/sendgridreceive',
'PhabricatorMetaMTAViewController' => 'applications/metamta/controller/view',
'PhabricatorMetaMTAWorker' => 'applications/metamta/worker',
'PhabricatorMustVerifyEmailController' => 'applications/auth/controller/mustverify',
'PhabricatorMySQLFileStorageEngine' => 'applications/files/engine/mysql',
'PhabricatorNotificationsController' => 'applications/notifications/controller/base',
'PhabricatorOAuthClientAuthorization' => 'applications/oauthserver/storage/clientauthorization',
'PhabricatorOAuthClientAuthorizationBaseController' => 'applications/oauthserver/controller/clientauthorization/base',
'PhabricatorOAuthClientAuthorizationDeleteController' => 'applications/oauthserver/controller/clientauthorization/delete',
'PhabricatorOAuthClientAuthorizationEditController' => 'applications/oauthserver/controller/clientauthorization/edit',
'PhabricatorOAuthClientAuthorizationListController' => 'applications/oauthserver/controller/clientauthorization/list',
'PhabricatorOAuthClientAuthorizationQuery' => 'applications/oauthserver/query/clientauthorization',
'PhabricatorOAuthClientBaseController' => 'applications/oauthserver/controller/client/base',
'PhabricatorOAuthClientDeleteController' => 'applications/oauthserver/controller/client/delete',
'PhabricatorOAuthClientEditController' => 'applications/oauthserver/controller/client/edit',
'PhabricatorOAuthClientListController' => 'applications/oauthserver/controller/client/list',
'PhabricatorOAuthClientViewController' => 'applications/oauthserver/controller/client/view',
'PhabricatorOAuthDefaultRegistrationController' => 'applications/auth/controller/oauthregistration/default',
'PhabricatorOAuthDiagnosticsController' => 'applications/auth/controller/oauthdiagnostics',
'PhabricatorOAuthFailureView' => 'applications/auth/view/oauthfailure',
'PhabricatorOAuthLoginController' => 'applications/auth/controller/oauth',
'PhabricatorOAuthProvider' => 'applications/auth/oauth/provider/base',
'PhabricatorOAuthProviderDisqus' => 'applications/auth/oauth/provider/disqus',
'PhabricatorOAuthProviderException' => 'applications/auth/oauth/provider/exception',
'PhabricatorOAuthProviderFacebook' => 'applications/auth/oauth/provider/facebook',
'PhabricatorOAuthProviderGitHub' => 'applications/auth/oauth/provider/github',
'PhabricatorOAuthProviderGoogle' => 'applications/auth/oauth/provider/google',
'PhabricatorOAuthProviderPhabricator' => 'applications/auth/oauth/provider/phabricator',
'PhabricatorOAuthRegistrationController' => 'applications/auth/controller/oauthregistration/base',
'PhabricatorOAuthResponse' => 'applications/oauthserver/response',
'PhabricatorOAuthServer' => 'applications/oauthserver/server',
'PhabricatorOAuthServerAccessToken' => 'applications/oauthserver/storage/accesstoken',
'PhabricatorOAuthServerAuthController' => 'applications/oauthserver/controller/auth',
'PhabricatorOAuthServerAuthorizationCode' => 'applications/oauthserver/storage/authorizationcode',
'PhabricatorOAuthServerClient' => 'applications/oauthserver/storage/client',
'PhabricatorOAuthServerClientQuery' => 'applications/oauthserver/query/client',
'PhabricatorOAuthServerController' => 'applications/oauthserver/controller/base',
'PhabricatorOAuthServerDAO' => 'applications/oauthserver/storage/base',
'PhabricatorOAuthServerScope' => 'applications/oauthserver/scope',
'PhabricatorOAuthServerTestCase' => 'applications/oauthserver/server/__tests__',
'PhabricatorOAuthServerTestController' => 'applications/oauthserver/controller/test',
'PhabricatorOAuthServerTokenController' => 'applications/oauthserver/controller/token',
'PhabricatorOAuthUnlinkController' => 'applications/auth/controller/unlink',
'PhabricatorObjectAttachmentEditor' => 'applications/search/editor/attach',
'PhabricatorObjectGraph' => 'applications/phid/graph',
'PhabricatorObjectHandle' => 'applications/phid/handle',
'PhabricatorObjectHandleConstants' => 'applications/phid/handle/const/base',
'PhabricatorObjectHandleData' => 'applications/phid/handle/data',
'PhabricatorObjectHandleStatus' => 'applications/phid/handle/const/status',
'PhabricatorObjectSelectorDialog' => 'view/control/objectselector',
'PhabricatorOffsetPagedQuery' => 'infrastructure/query/offsetpaged',
'PhabricatorOwnerPathQuery' => 'applications/owners/query/path',
'PhabricatorOwnersController' => 'applications/owners/controller/base',
'PhabricatorOwnersDAO' => 'applications/owners/storage/base',
'PhabricatorOwnersDeleteController' => 'applications/owners/controller/delete',
'PhabricatorOwnersDetailController' => 'applications/owners/controller/detail',
'PhabricatorOwnersEditController' => 'applications/owners/controller/edit',
'PhabricatorOwnersListController' => 'applications/owners/controller/list',
'PhabricatorOwnersOwner' => 'applications/owners/storage/owner',
'PhabricatorOwnersPackage' => 'applications/owners/storage/package',
'PhabricatorOwnersPath' => 'applications/owners/storage/path',
'PhabricatorPHID' => 'applications/phid/storage/phid',
'PhabricatorPHIDConstants' => 'applications/phid/constants',
'PhabricatorPHIDController' => 'applications/phid/controller/base',
'PhabricatorPHIDLookupController' => 'applications/phid/controller/lookup',
'PhabricatorPaste' => 'applications/paste/storage/paste',
'PhabricatorPasteController' => 'applications/paste/controller/base',
'PhabricatorPasteDAO' => 'applications/paste/storage/base',
'PhabricatorPasteListController' => 'applications/paste/controller/list',
'PhabricatorPasteQuery' => 'applications/paste/query/paste',
'PhabricatorPasteViewController' => 'applications/paste/controller/view',
'PhabricatorPeopleController' => 'applications/people/controller/base',
'PhabricatorPeopleEditController' => 'applications/people/controller/edit',
'PhabricatorPeopleListController' => 'applications/people/controller/list',
'PhabricatorPeopleLogsController' => 'applications/people/controller/logs',
'PhabricatorPeopleProfileController' => 'applications/people/controller/profile',
'PhabricatorPeopleQuery' => 'applications/people/query',
'PhabricatorPolicies' => 'applications/policy/constants/policy',
'PhabricatorPolicyCapability' => 'applications/policy/constants/capability',
'PhabricatorPolicyConstants' => 'applications/policy/constants/base',
'PhabricatorPolicyException' => 'applications/policy/exception/base',
'PhabricatorPolicyFilter' => 'applications/policy/filter/policy',
'PhabricatorPolicyInterface' => 'applications/policy/interface/policy',
'PhabricatorPolicyQuery' => 'infrastructure/query/policy/base',
'PhabricatorPolicyTestCase' => 'applications/policy/__tests__',
'PhabricatorPolicyTestObject' => 'applications/policy/__tests__',
'PhabricatorPolicyTestQuery' => 'applications/policy/__tests__',
'PhabricatorProfileHeaderView' => 'view/layout/profileheader',
'PhabricatorProject' => 'applications/project/storage/project',
'PhabricatorProjectAffiliation' => 'applications/project/storage/affiliation',
'PhabricatorProjectConstants' => 'applications/project/constants/base',
'PhabricatorProjectController' => 'applications/project/controller/base',
'PhabricatorProjectCreateController' => 'applications/project/controller/create',
'PhabricatorProjectDAO' => 'applications/project/storage/base',
'PhabricatorProjectEditor' => 'applications/project/editor/project',
'PhabricatorProjectListController' => 'applications/project/controller/list',
'PhabricatorProjectNameCollisionException' => 'applications/project/exception/namecollison',
'PhabricatorProjectProfile' => 'applications/project/storage/profile',
'PhabricatorProjectProfileController' => 'applications/project/controller/profile',
'PhabricatorProjectProfileEditController' => 'applications/project/controller/profileedit',
'PhabricatorProjectQuery' => 'applications/project/query/project',
'PhabricatorProjectStatus' => 'applications/project/constants/status',
'PhabricatorProjectSubproject' => 'applications/project/storage/subproject',
'PhabricatorProjectTransaction' => 'applications/project/storage/transaction',
'PhabricatorProjectTransactionType' => 'applications/project/constants/transaction',
'PhabricatorProjectUpdateController' => 'applications/project/controller/update',
'PhabricatorQuery' => 'infrastructure/query/base',
'PhabricatorRedirectController' => 'applications/base/controller/redirect',
'PhabricatorRefreshCSRFController' => 'applications/auth/controller/refresh',
'PhabricatorRemarkupRuleDifferential' => 'infrastructure/markup/remarkup/markuprule/differential',
'PhabricatorRemarkupRuleDifferentialHandle' => 'infrastructure/markup/remarkup/markuprule/handle/differential',
'PhabricatorRemarkupRuleDiffusion' => 'infrastructure/markup/remarkup/markuprule/diffusion',
'PhabricatorRemarkupRuleEmbedFile' => 'infrastructure/markup/remarkup/markuprule/embedobject',
'PhabricatorRemarkupRuleImageMacro' => 'infrastructure/markup/remarkup/markuprule/imagemacro',
'PhabricatorRemarkupRuleManiphest' => 'infrastructure/markup/remarkup/markuprule/maniphest',
'PhabricatorRemarkupRuleManiphestHandle' => 'infrastructure/markup/remarkup/markuprule/handle/maniphest',
'PhabricatorRemarkupRuleMention' => 'infrastructure/markup/remarkup/markuprule/mention',
'PhabricatorRemarkupRuleObjectHandle' => 'infrastructure/markup/remarkup/markuprule/handle',
'PhabricatorRemarkupRuleObjectName' => 'infrastructure/markup/remarkup/markuprule/objectname',
'PhabricatorRemarkupRulePaste' => 'infrastructure/markup/remarkup/markuprule/paste',
'PhabricatorRemarkupRulePhriction' => 'infrastructure/markup/remarkup/markuprule/phriction',
'PhabricatorRemarkupRuleProxyImage' => 'infrastructure/markup/remarkup/markuprule/proxyimage',
'PhabricatorRemarkupRuleYoutube' => 'infrastructure/markup/remarkup/markuprule/youtube',
'PhabricatorRepository' => 'applications/repository/storage/repository',
'PhabricatorRepositoryArcanistProject' => 'applications/repository/storage/arcanistproject',
'PhabricatorRepositoryArcanistProjectEditController' => 'applications/repository/controller/arcansistprojectedit',
'PhabricatorRepositoryAuditRequest' => 'applications/repository/storage/auditrequest',
'PhabricatorRepositoryCommit' => 'applications/repository/storage/commit',
'PhabricatorRepositoryCommitChangeParserWorker' => 'applications/repository/worker/commitchangeparser/base',
'PhabricatorRepositoryCommitData' => 'applications/repository/storage/commitdata',
'PhabricatorRepositoryCommitHeraldWorker' => 'applications/repository/worker/herald',
'PhabricatorRepositoryCommitMessageDetailParser' => 'applications/repository/parser/base',
'PhabricatorRepositoryCommitMessageParserWorker' => 'applications/repository/worker/commitmessageparser/base',
'PhabricatorRepositoryCommitOwnersWorker' => 'applications/repository/worker/owner',
'PhabricatorRepositoryCommitParserWorker' => 'applications/repository/worker/base',
'PhabricatorRepositoryController' => 'applications/repository/controller/base',
'PhabricatorRepositoryCreateController' => 'applications/repository/controller/create',
'PhabricatorRepositoryDAO' => 'applications/repository/storage/base',
'PhabricatorRepositoryDefaultCommitMessageDetailParser' => 'applications/repository/parser/default',
'PhabricatorRepositoryDeleteController' => 'applications/repository/controller/delete',
'PhabricatorRepositoryEditController' => 'applications/repository/controller/edit',
'PhabricatorRepositoryGitCommitChangeParserWorker' => 'applications/repository/worker/commitchangeparser/git',
'PhabricatorRepositoryGitCommitMessageParserWorker' => 'applications/repository/worker/commitmessageparser/git',
'PhabricatorRepositoryListController' => 'applications/repository/controller/list',
'PhabricatorRepositoryMercurialCommitChangeParserWorker' => 'applications/repository/worker/commitchangeparser/mercurial',
'PhabricatorRepositoryMercurialCommitMessageParserWorker' => 'applications/repository/worker/commitmessageparser/mercurial',
'PhabricatorRepositoryPullLocalDaemon' => 'applications/repository/daemon/pulllocal',
'PhabricatorRepositoryPullLocalDaemonTestCase' => 'applications/repository/daemon/pulllocal/__tests__',
'PhabricatorRepositoryShortcut' => 'applications/repository/storage/shortcut',
'PhabricatorRepositorySvnCommitChangeParserWorker' => 'applications/repository/worker/commitchangeparser/svn',
'PhabricatorRepositorySvnCommitMessageParserWorker' => 'applications/repository/worker/commitmessageparser/svn',
'PhabricatorRepositorySymbol' => 'applications/repository/storage/symbol',
'PhabricatorRepositoryTestCase' => 'applications/repository/storage/repository/__tests__',
'PhabricatorRepositoryType' => 'applications/repository/constants/repositorytype',
'PhabricatorS3FileStorageEngine' => 'applications/files/engine/s3',
'PhabricatorSQLPatchList' => 'infrastructure/setup/sql/base',
'PhabricatorScopedEnv' => 'infrastructure/env',
'PhabricatorSearchAbstractDocument' => 'applications/search/index/abstractdocument',
'PhabricatorSearchAttachController' => 'applications/search/controller/attach',
'PhabricatorSearchBaseController' => 'applications/search/controller/base',
'PhabricatorSearchCommitIndexer' => 'applications/search/index/indexer/repository',
'PhabricatorSearchController' => 'applications/search/controller/search',
'PhabricatorSearchDAO' => 'applications/search/storage/base',
'PhabricatorSearchDifferentialIndexer' => 'applications/search/index/indexer/differential',
'PhabricatorSearchDocument' => 'applications/search/storage/document/document',
'PhabricatorSearchDocumentField' => 'applications/search/storage/document/field',
'PhabricatorSearchDocumentIndexer' => 'applications/search/index/indexer/base',
'PhabricatorSearchDocumentRelationship' => 'applications/search/storage/document/relationship',
'PhabricatorSearchEngine' => 'applications/search/engine/base',
'PhabricatorSearchEngineElastic' => 'applications/search/engine/elastic',
'PhabricatorSearchEngineMySQL' => 'applications/search/engine/mysql',
'PhabricatorSearchEngineSelector' => 'applications/search/selector/base',
'PhabricatorSearchField' => 'applications/search/constants/field',
'PhabricatorSearchIndexController' => 'applications/search/controller/index',
'PhabricatorSearchManiphestIndexer' => 'applications/search/index/indexer/maniphest',
'PhabricatorSearchPhrictionIndexer' => 'applications/search/index/indexer/phriction',
'PhabricatorSearchQuery' => 'applications/search/storage/query',
'PhabricatorSearchRelationship' => 'applications/search/constants/relationship',
'PhabricatorSearchResultView' => 'applications/search/view/searchresult',
'PhabricatorSearchScope' => 'applications/search/constants/scope',
'PhabricatorSearchSelectController' => 'applications/search/controller/select',
'PhabricatorSearchUserIndexer' => 'applications/search/index/indexer/user',
'PhabricatorSetup' => 'infrastructure/setup',
'PhabricatorSlowvoteChoice' => 'applications/slowvote/storage/choice',
'PhabricatorSlowvoteComment' => 'applications/slowvote/storage/comment',
'PhabricatorSlowvoteController' => 'applications/slowvote/controller/base',
'PhabricatorSlowvoteCreateController' => 'applications/slowvote/controller/create',
'PhabricatorSlowvoteDAO' => 'applications/slowvote/storage/base',
'PhabricatorSlowvoteListController' => 'applications/slowvote/controller/list',
'PhabricatorSlowvoteOption' => 'applications/slowvote/storage/option',
'PhabricatorSlowvotePoll' => 'applications/slowvote/storage/poll',
'PhabricatorSlowvotePollController' => 'applications/slowvote/controller/poll',
'PhabricatorSlug' => 'infrastructure/util/slug',
'PhabricatorSlugTestCase' => 'infrastructure/util/slug/__tests__',
'PhabricatorSortTableExample' => 'applications/uiexample/examples/sorttable',
'PhabricatorStandardPageView' => 'view/page/standard',
'PhabricatorStatusController' => 'applications/status/base',
'PhabricatorStorageFixtureScopeGuard' => 'infrastructure/testing/fixture/storage',
'PhabricatorStorageManagementAPI' => 'infrastructure/setup/storage/management',
'PhabricatorStorageManagementDatabasesWorkflow' => 'infrastructure/setup/storage/workflow/databases',
'PhabricatorStorageManagementDestroyWorkflow' => 'infrastructure/setup/storage/workflow/destroy',
'PhabricatorStorageManagementDumpWorkflow' => 'infrastructure/setup/storage/workflow/dump',
'PhabricatorStorageManagementStatusWorkflow' => 'infrastructure/setup/storage/workflow/status',
'PhabricatorStorageManagementUpgradeWorkflow' => 'infrastructure/setup/storage/workflow/upgrade',
'PhabricatorStorageManagementWorkflow' => 'infrastructure/setup/storage/workflow/base',
'PhabricatorStoragePatch' => 'infrastructure/setup/storage/patch',
'PhabricatorSymbolNameLinter' => 'infrastructure/lint/hook/xhpastsymbolname',
'PhabricatorSyntaxHighlighter' => 'applications/markup/syntax',
'PhabricatorTaskmasterDaemon' => 'infrastructure/daemon/workers/taskmaster',
'PhabricatorTestCase' => 'infrastructure/testing/testcase',
'PhabricatorTimelineCursor' => 'infrastructure/daemon/timeline/storage/cursor',
'PhabricatorTimelineDAO' => 'infrastructure/daemon/timeline/storage/base',
'PhabricatorTimelineEvent' => 'infrastructure/daemon/timeline/storage/event',
'PhabricatorTimelineEventData' => 'infrastructure/daemon/timeline/storage/eventdata',
'PhabricatorTimelineIterator' => 'infrastructure/daemon/timeline/cursor/iterator',
'PhabricatorTimer' => 'applications/countdown/storage/timer',
'PhabricatorTransactionView' => 'view/layout/transaction',
'PhabricatorTransformedFile' => 'applications/files/storage/transformed',
'PhabricatorTrivialTestCase' => 'infrastructure/testing/testcase/__tests__',
'PhabricatorTypeaheadCommonDatasourceController' => 'applications/typeahead/controller/common',
'PhabricatorTypeaheadDatasourceController' => 'applications/typeahead/controller/base',
'PhabricatorUIExample' => 'applications/uiexample/examples/base',
'PhabricatorUIExampleController' => 'applications/uiexample/controller/base',
'PhabricatorUIExampleRenderController' => 'applications/uiexample/controller/render',
'PhabricatorUIListFilterExample' => 'applications/uiexample/examples/listfilter',
'PhabricatorUIPagerExample' => 'applications/uiexample/examples/pager',
'PhabricatorUITooltipExample' => 'applications/uiexample/examples/tooltip',
'PhabricatorUnitsTestCase' => 'view/utils/__tests__',
'PhabricatorUser' => 'applications/people/storage/user',
'PhabricatorUserAccountSettingsPanelController' => 'applications/people/controller/settings/panels/account',
'PhabricatorUserConduitSettingsPanelController' => 'applications/people/controller/settings/panels/conduit',
'PhabricatorUserDAO' => 'applications/people/storage/base',
'PhabricatorUserEditor' => 'applications/people/editor',
'PhabricatorUserEmail' => 'applications/people/storage/email',
'PhabricatorUserEmailPreferenceSettingsPanelController' => 'applications/people/controller/settings/panels/emailpref',
'PhabricatorUserEmailSettingsPanelController' => 'applications/people/controller/settings/panels/email',
'PhabricatorUserLog' => 'applications/people/storage/log',
'PhabricatorUserOAuthInfo' => 'applications/people/storage/useroauthinfo',
'PhabricatorUserOAuthSettingsPanelController' => 'applications/people/controller/settings/panels/oauth',
'PhabricatorUserPasswordSettingsPanelController' => 'applications/people/controller/settings/panels/password',
'PhabricatorUserPreferenceSettingsPanelController' => 'applications/people/controller/settings/panels/preferences',
'PhabricatorUserPreferences' => 'applications/people/storage/preferences',
'PhabricatorUserProfile' => 'applications/people/storage/profile',
'PhabricatorUserProfileSettingsPanelController' => 'applications/people/controller/settings/panels/profile',
'PhabricatorUserSSHKey' => 'applications/people/storage/usersshkey',
'PhabricatorUserSSHKeysSettingsPanelController' => 'applications/people/controller/settings/panels/sshkeys',
'PhabricatorUserSearchSettingsPanelController' => 'applications/people/controller/settings/panels/search',
'PhabricatorUserSettingsController' => 'applications/people/controller/settings',
'PhabricatorUserSettingsPanelController' => 'applications/people/controller/settings/panels/base',
'PhabricatorUserStatus' => 'applications/people/storage/userstatus',
'PhabricatorUserTestCase' => 'applications/people/storage/user/__tests__',
'PhabricatorWorker' => 'infrastructure/daemon/workers/worker',
'PhabricatorWorkerDAO' => 'infrastructure/daemon/workers/storage/base',
'PhabricatorWorkerTask' => 'infrastructure/daemon/workers/storage/task',
'PhabricatorWorkerTaskData' => 'infrastructure/daemon/workers/storage/taskdata',
'PhabricatorWorkerTaskDetailController' => 'applications/daemon/controller/workertaskdetail',
'PhabricatorWorkerTaskUpdateController' => 'applications/daemon/controller/workertaskupdate',
'PhabricatorXHPASTViewController' => 'applications/xhpastview/controller/base',
'PhabricatorXHPASTViewDAO' => 'applications/xhpastview/storage/base',
'PhabricatorXHPASTViewFrameController' => 'applications/xhpastview/controller/viewframe',
'PhabricatorXHPASTViewFramesetController' => 'applications/xhpastview/controller/viewframeset',
'PhabricatorXHPASTViewInputController' => 'applications/xhpastview/controller/viewinput',
'PhabricatorXHPASTViewPanelController' => 'applications/xhpastview/controller/viewpanel',
'PhabricatorXHPASTViewParseTree' => 'applications/xhpastview/storage/parsetree',
'PhabricatorXHPASTViewRunController' => 'applications/xhpastview/controller/run',
'PhabricatorXHPASTViewStreamController' => 'applications/xhpastview/controller/viewstream',
'PhabricatorXHPASTViewTreeController' => 'applications/xhpastview/controller/viewtree',
'PhabricatorXHProfController' => 'applications/xhprof/controller/base',
'PhabricatorXHProfProfileController' => 'applications/xhprof/controller/profile',
'PhabricatorXHProfProfileSymbolView' => 'applications/xhprof/view/symbol',
'PhabricatorXHProfProfileTopLevelView' => 'applications/xhprof/view/toplevel',
'PhabricatorXHProfProfileView' => 'applications/xhprof/view/base',
'PhameController' => 'applications/phame/controller/base',
'PhameDAO' => 'applications/phame/storage/base',
'PhameDraftListController' => 'applications/phame/controller/post/list/drafts',
'PhamePost' => 'applications/phame/storage/post',
'PhamePostDeleteController' => 'applications/phame/controller/post/delete',
'PhamePostDetailView' => 'applications/phame/view/postdetail',
'PhamePostEditController' => 'applications/phame/controller/post/edit',
'PhamePostListBaseController' => 'applications/phame/controller/post/list/base',
'PhamePostListController' => 'applications/phame/controller/post/list/posts',
'PhamePostListView' => 'applications/phame/view/postlist',
'PhamePostPreviewController' => 'applications/phame/controller/post/preview',
'PhamePostQuery' => 'applications/phame/query/post',
'PhamePostViewController' => 'applications/phame/controller/post/view',
'PhortuneMonthYearExpiryControl' => 'applications/phortune/control/monthyearexpiry',
'PhortuneStripeBaseController' => 'applications/phortune/stripe/controller/base',
'PhortuneStripePaymentFormView' => 'applications/phortune/stripe/view/paymentform',
'PhortuneStripeTestPaymentFormController' => 'applications/phortune/stripe/controller/testpaymentform',
'PhrictionActionConstants' => 'applications/phriction/constants/action',
'PhrictionChangeType' => 'applications/phriction/constants/changetype',
'PhrictionConstants' => 'applications/phriction/constants/base',
'PhrictionContent' => 'applications/phriction/storage/content',
'PhrictionController' => 'applications/phriction/controller/base',
'PhrictionDAO' => 'applications/phriction/storage/base',
'PhrictionDeleteController' => 'applications/phriction/controller/delete',
'PhrictionDiffController' => 'applications/phriction/controller/diff',
'PhrictionDocument' => 'applications/phriction/storage/document',
'PhrictionDocumentController' => 'applications/phriction/controller/document',
'PhrictionDocumentEditor' => 'applications/phriction/editor/document',
'PhrictionDocumentPreviewController' => 'applications/phriction/controller/documentpreview',
'PhrictionDocumentStatus' => 'applications/phriction/constants/documentstatus',
'PhrictionDocumentTestCase' => 'applications/phriction/storage/document/__tests__',
'PhrictionEditController' => 'applications/phriction/controller/edit',
'PhrictionHistoryController' => 'applications/phriction/controller/history',
'PhrictionListController' => 'applications/phriction/controller/list',
'QueryFormattingTestCase' => 'storage/qsprintf/__tests__',
),
'function' =>
array(
'_phabricator_date_format' => 'view/utils',
'_qsprintf_check_scalar_type' => 'storage/qsprintf',
'_qsprintf_check_type' => 'storage/qsprintf',
'celerity_generate_unique_node_id' => 'infrastructure/celerity/api',
'celerity_get_resource_uri' => 'infrastructure/celerity/api',
'celerity_register_resource_map' => 'infrastructure/celerity/map',
'javelin_render_tag' => 'infrastructure/javelin/markup',
'phabricator_date' => 'view/utils',
'phabricator_datetime' => 'view/utils',
'phabricator_format_bytes' => 'view/utils',
'phabricator_format_local_time' => 'view/utils',
'phabricator_format_relative_time' => 'view/utils',
'phabricator_format_units_generic' => 'view/utils',
'phabricator_on_relative_date' => 'view/utils',
'phabricator_parse_bytes' => 'view/utils',
'phabricator_relative_date' => 'view/utils',
'phabricator_render_form' => 'infrastructure/javelin/markup',
'phabricator_time' => 'view/utils',
'phid_get_type' => 'applications/phid/utils',
'phid_group_by_type' => 'applications/phid/utils',
'qsprintf' => 'storage/qsprintf',
'queryfx' => 'storage/queryfx',
'queryfx_all' => 'storage/queryfx',
'queryfx_one' => 'storage/queryfx',
'require_celerity_resource' => 'infrastructure/celerity/api',
'vqsprintf' => 'storage/qsprintf',
'vqueryfx' => 'storage/queryfx',
'vqueryfx_all' => 'storage/queryfx',
'xsprintf_query' => 'storage/qsprintf',
),
'requires_class' =>
array(
'Aphront304Response' => 'AphrontResponse',
'Aphront400Response' => 'AphrontResponse',
'Aphront403Response' => 'AphrontWebpageResponse',
'Aphront404Response' => 'AphrontWebpageResponse',
'AphrontAjaxResponse' => 'AphrontResponse',
'AphrontAttachedFileView' => 'AphrontView',
'AphrontCSRFException' => 'AphrontException',
'AphrontCalendarEventView' => 'AphrontView',
'AphrontCalendarMonthView' => 'AphrontView',
'AphrontContextBarView' => 'AphrontView',
'AphrontCrumbsView' => 'AphrontView',
'AphrontDefaultApplicationConfiguration' => 'AphrontApplicationConfiguration',
'AphrontDialogResponse' => 'AphrontResponse',
'AphrontDialogView' => 'AphrontView',
'AphrontErrorView' => 'AphrontView',
'AphrontFilePreviewView' => 'AphrontView',
'AphrontFileResponse' => 'AphrontResponse',
'AphrontFormCheckboxControl' => 'AphrontFormControl',
'AphrontFormControl' => 'AphrontView',
'AphrontFormDateControl' => 'AphrontFormControl',
'AphrontFormDividerControl' => 'AphrontFormControl',
'AphrontFormDragAndDropUploadControl' => 'AphrontFormControl',
'AphrontFormFileControl' => 'AphrontFormControl',
'AphrontFormInsetView' => 'AphrontView',
'AphrontFormLayoutView' => 'AphrontView',
'AphrontFormMarkupControl' => 'AphrontFormControl',
'AphrontFormPasswordControl' => 'AphrontFormControl',
'AphrontFormPolicyControl' => 'AphrontFormControl',
'AphrontFormRadioButtonControl' => 'AphrontFormControl',
'AphrontFormRecaptchaControl' => 'AphrontFormControl',
'AphrontFormSelectControl' => 'AphrontFormControl',
'AphrontFormStaticControl' => 'AphrontFormControl',
'AphrontFormSubmitControl' => 'AphrontFormControl',
'AphrontFormTextAreaControl' => 'AphrontFormControl',
'AphrontFormTextControl' => 'AphrontFormControl',
'AphrontFormToggleButtonsControl' => 'AphrontFormControl',
'AphrontFormTokenizerControl' => 'AphrontFormControl',
'AphrontFormView' => 'AphrontView',
'AphrontHTTPSinkTestCase' => 'PhabricatorTestCase',
'AphrontHeadsupActionListView' => 'AphrontView',
'AphrontHeadsupActionView' => 'AphrontView',
'AphrontHeadsupView' => 'AphrontView',
'AphrontIDPagerView' => 'AphrontView',
'AphrontIsolatedDatabaseConnection' => 'AphrontDatabaseConnection',
'AphrontIsolatedDatabaseConnectionTestCase' => 'PhabricatorTestCase',
'AphrontIsolatedHTTPSink' => 'AphrontHTTPSink',
'AphrontJSONResponse' => 'AphrontResponse',
'AphrontJavelinView' => 'AphrontView',
'AphrontKeyboardShortcutsAvailableView' => 'AphrontView',
'AphrontListFilterView' => 'AphrontView',
'AphrontMiniPanelView' => 'AphrontView',
'AphrontMoreView' => 'AphrontView',
'AphrontMySQLDatabaseConnection' => 'AphrontMySQLDatabaseConnectionBase',
'AphrontMySQLDatabaseConnectionBase' => 'AphrontDatabaseConnection',
'AphrontMySQLDatabaseConnectionTestCase' => 'PhabricatorTestCase',
'AphrontMySQLiDatabaseConnection' => 'AphrontMySQLDatabaseConnectionBase',
'AphrontNullView' => 'AphrontView',
'AphrontPHPHTTPSink' => 'AphrontHTTPSink',
'AphrontPageView' => 'AphrontView',
'AphrontPagerView' => 'AphrontView',
'AphrontPanelView' => 'AphrontView',
'AphrontPlainTextResponse' => 'AphrontResponse',
'AphrontProxyResponse' => 'AphrontResponse',
'AphrontQueryAccessDeniedException' => 'AphrontQueryRecoverableException',
'AphrontQueryConnectionException' => 'AphrontQueryException',
'AphrontQueryConnectionLostException' => 'AphrontQueryRecoverableException',
'AphrontQueryCountException' => 'AphrontQueryException',
'AphrontQueryDeadlockException' => 'AphrontQueryRecoverableException',
'AphrontQueryDuplicateKeyException' => 'AphrontQueryException',
'AphrontQueryObjectMissingException' => 'AphrontQueryException',
'AphrontQueryParameterException' => 'AphrontQueryException',
'AphrontQueryRecoverableException' => 'AphrontQueryException',
'AphrontQuerySchemaException' => 'AphrontQueryException',
'AphrontRedirectException' => 'AphrontException',
'AphrontRedirectResponse' => 'AphrontResponse',
'AphrontReloadResponse' => 'AphrontRedirectResponse',
'AphrontRequestFailureView' => 'AphrontView',
'AphrontRequestTestCase' => 'PhabricatorTestCase',
'AphrontSideNavFilterView' => 'AphrontView',
'AphrontSideNavView' => 'AphrontView',
'AphrontTableView' => 'AphrontView',
'AphrontTokenizerTemplateView' => 'AphrontView',
'AphrontTypeaheadTemplateView' => 'AphrontView',
'AphrontUsageException' => 'AphrontException',
'AphrontWebpageResponse' => 'AphrontResponse',
'CelerityResourceController' => 'AphrontController',
'CelerityResourceGraph' => 'AbstractDirectedGraph',
'CelerityResourceTransformerTestCase' => 'PhabricatorTestCase',
'ConduitAPI_arcanist_Method' => 'ConduitAPIMethod',
'ConduitAPI_arcanist_projectinfo_Method' => 'ConduitAPI_arcanist_Method',
'ConduitAPI_audit_Method' => 'ConduitAPIMethod',
'ConduitAPI_audit_query_Method' => 'ConduitAPI_audit_Method',
'ConduitAPI_chatlog_Method' => 'ConduitAPIMethod',
'ConduitAPI_chatlog_query_Method' => 'ConduitAPI_chatlog_Method',
'ConduitAPI_chatlog_record_Method' => 'ConduitAPI_chatlog_Method',
'ConduitAPI_conduit_connect_Method' => 'ConduitAPIMethod',
'ConduitAPI_conduit_getcertificate_Method' => 'ConduitAPIMethod',
'ConduitAPI_conduit_ping_Method' => 'ConduitAPIMethod',
'ConduitAPI_daemon_launched_Method' => 'ConduitAPIMethod',
'ConduitAPI_daemon_log_Method' => 'ConduitAPIMethod',
'ConduitAPI_differential_close_Method' => 'ConduitAPIMethod',
'ConduitAPI_differential_createcomment_Method' => 'ConduitAPIMethod',
'ConduitAPI_differential_creatediff_Method' => 'ConduitAPIMethod',
'ConduitAPI_differential_createrevision_Method' => 'ConduitAPIMethod',
'ConduitAPI_differential_find_Method' => 'ConduitAPIMethod',
'ConduitAPI_differential_getalldiffs_Method' => 'ConduitAPIMethod',
'ConduitAPI_differential_getcommitmessage_Method' => 'ConduitAPIMethod',
'ConduitAPI_differential_getcommitpaths_Method' => 'ConduitAPIMethod',
'ConduitAPI_differential_getdiff_Method' => 'ConduitAPIMethod',
'ConduitAPI_differential_getrevision_Method' => 'ConduitAPIMethod',
'ConduitAPI_differential_getrevisioncomments_Method' => 'ConduitAPIMethod',
'ConduitAPI_differential_getrevisionfeedback_Method' => 'ConduitAPIMethod',
'ConduitAPI_differential_markcommitted_Method' => 'ConduitAPIMethod',
'ConduitAPI_differential_parsecommitmessage_Method' => 'ConduitAPIMethod',
'ConduitAPI_differential_query_Method' => 'ConduitAPIMethod',
'ConduitAPI_differential_setdiffproperty_Method' => 'ConduitAPIMethod',
'ConduitAPI_differential_updaterevision_Method' => 'ConduitAPIMethod',
'ConduitAPI_differential_updatetaskrevisionassoc_Method' => 'ConduitAPIMethod',
'ConduitAPI_differential_updateunitresults_Method' => 'ConduitAPIMethod',
'ConduitAPI_diffusion_findsymbols_Method' => 'ConduitAPIMethod',
'ConduitAPI_diffusion_getcommits_Method' => 'ConduitAPIMethod',
'ConduitAPI_diffusion_getrecentcommitsbypath_Method' => 'ConduitAPIMethod',
'ConduitAPI_feed_publish_Method' => 'ConduitAPIMethod',
'ConduitAPI_feed_query_Method' => 'ConduitAPIMethod',
'ConduitAPI_file_download_Method' => 'ConduitAPIMethod',
'ConduitAPI_file_info_Method' => 'ConduitAPIMethod',
'ConduitAPI_file_upload_Method' => 'ConduitAPIMethod',
'ConduitAPI_flag_Method' => 'ConduitAPIMethod',
'ConduitAPI_flag_query_Method' => 'ConduitAPI_flag_Method',
'ConduitAPI_macro_Method' => 'ConduitAPIMethod',
'ConduitAPI_macro_query_Method' => 'ConduitAPI_macro_Method',
'ConduitAPI_maniphest_Method' => 'ConduitAPIMethod',
'ConduitAPI_maniphest_createtask_Method' => 'ConduitAPI_maniphest_Method',
'ConduitAPI_maniphest_find_Method' => 'ConduitAPI_maniphest_Method',
'ConduitAPI_maniphest_gettasktransactions_Method' => 'ConduitAPI_maniphest_Method',
'ConduitAPI_maniphest_info_Method' => 'ConduitAPI_maniphest_Method',
'ConduitAPI_maniphest_update_Method' => 'ConduitAPI_maniphest_Method',
'ConduitAPI_owners_query_Method' => 'ConduitAPIMethod',
'ConduitAPI_paste_Method' => 'ConduitAPIMethod',
'ConduitAPI_paste_create_Method' => 'ConduitAPI_paste_Method',
'ConduitAPI_paste_info_Method' => 'ConduitAPI_paste_Method',
'ConduitAPI_path_getowners_Method' => 'ConduitAPIMethod',
'ConduitAPI_phid_Method' => 'ConduitAPIMethod',
'ConduitAPI_phid_info_Method' => 'ConduitAPI_phid_Method',
'ConduitAPI_phid_query_Method' => 'ConduitAPI_phid_Method',
'ConduitAPI_phriction_Method' => 'ConduitAPIMethod',
'ConduitAPI_phriction_edit_Method' => 'ConduitAPI_phriction_Method',
'ConduitAPI_phriction_history_Method' => 'ConduitAPI_phriction_Method',
'ConduitAPI_phriction_info_Method' => 'ConduitAPI_phriction_Method',
'ConduitAPI_project_Method' => 'ConduitAPIMethod',
'ConduitAPI_project_query_Method' => 'ConduitAPI_project_Method',
'ConduitAPI_remarkup_process_Method' => 'ConduitAPIMethod',
'ConduitAPI_repository_Method' => 'ConduitAPIMethod',
'ConduitAPI_repository_create_Method' => 'ConduitAPI_repository_Method',
'ConduitAPI_repository_query_Method' => 'ConduitAPI_repository_Method',
'ConduitAPI_slowvote_info_Method' => 'ConduitAPIMethod',
'ConduitAPI_user_Method' => 'ConduitAPIMethod',
'ConduitAPI_user_addstatus_Method' => 'ConduitAPI_user_Method',
'ConduitAPI_user_disable_Method' => 'ConduitAPI_user_Method',
'ConduitAPI_user_find_Method' => 'ConduitAPI_user_Method',
'ConduitAPI_user_info_Method' => 'ConduitAPI_user_Method',
'ConduitAPI_user_query_Method' => 'ConduitAPI_user_Method',
'ConduitAPI_user_removestatus_Method' => 'ConduitAPI_user_Method',
'ConduitAPI_user_whoami_Method' => 'ConduitAPI_user_Method',
'DarkConsoleConfigPlugin' => 'DarkConsolePlugin',
'DarkConsoleController' => 'PhabricatorController',
'DarkConsoleErrorLogPlugin' => 'DarkConsolePlugin',
'DarkConsoleEventPlugin' => 'DarkConsolePlugin',
'DarkConsoleEventPluginAPI' => 'PhutilEventListener',
'DarkConsoleRequestPlugin' => 'DarkConsolePlugin',
'DarkConsoleServicesPlugin' => 'DarkConsolePlugin',
'DarkConsoleXHProfPlugin' => 'DarkConsolePlugin',
'DifferentialActionHasNoEffectException' => 'DifferentialException',
'DifferentialAddCommentView' => 'AphrontView',
'DifferentialAffectedPath' => 'DifferentialDAO',
'DifferentialApplyPatchFieldSpecification' => 'DifferentialFieldSpecification',
'DifferentialArcanistProjectFieldSpecification' => 'DifferentialFieldSpecification',
'DifferentialAuditorsFieldSpecification' => 'DifferentialFieldSpecification',
'DifferentialAuthorFieldSpecification' => 'DifferentialFieldSpecification',
'DifferentialAuxiliaryField' => 'DifferentialDAO',
'DifferentialBlameRevisionFieldSpecification' => 'DifferentialFieldSpecification',
'DifferentialBranchFieldSpecification' => 'DifferentialFieldSpecification',
'DifferentialCCWelcomeMail' => 'DifferentialReviewRequestMail',
'DifferentialCCsFieldSpecification' => 'DifferentialFieldSpecification',
'DifferentialChangeset' => 'DifferentialDAO',
'DifferentialChangesetDetailView' => 'AphrontView',
'DifferentialChangesetListView' => 'AphrontView',
'DifferentialChangesetViewController' => 'DifferentialController',
'DifferentialComment' => 'DifferentialDAO',
'DifferentialCommentMail' => 'DifferentialMail',
'DifferentialCommentPreviewController' => 'DifferentialController',
'DifferentialCommentSaveController' => 'DifferentialController',
'DifferentialCommitsFieldSpecification' => 'DifferentialFieldSpecification',
'DifferentialController' => 'PhabricatorController',
'DifferentialDAO' => 'PhabricatorLiskDAO',
'DifferentialDateCreatedFieldSpecification' => 'DifferentialFieldSpecification',
'DifferentialDateModifiedFieldSpecification' => 'DifferentialFieldSpecification',
'DifferentialDefaultFieldSelector' => 'DifferentialFieldSelector',
'DifferentialDependenciesFieldSpecification' => 'DifferentialFieldSpecification',
'DifferentialDiff' => 'DifferentialDAO',
'DifferentialDiffContentMail' => 'DifferentialMail',
'DifferentialDiffCreateController' => 'DifferentialController',
'DifferentialDiffProperty' => 'DifferentialDAO',
'DifferentialDiffTableOfContentsView' => 'AphrontView',
'DifferentialDiffViewController' => 'DifferentialController',
'DifferentialExceptionMail' => 'DifferentialMail',
'DifferentialExportPatchFieldSpecification' => 'DifferentialFieldSpecification',
'DifferentialGitSVNIDFieldSpecification' => 'DifferentialFieldSpecification',
'DifferentialHostFieldSpecification' => 'DifferentialFieldSpecification',
'DifferentialHunk' => 'DifferentialDAO',
'DifferentialInlineComment' => 'DifferentialDAO',
'DifferentialInlineCommentEditController' => 'PhabricatorInlineCommentController',
'DifferentialInlineCommentEditView' => 'AphrontView',
'DifferentialInlineCommentPreviewController' => 'DifferentialController',
'DifferentialInlineCommentView' => 'AphrontView',
'DifferentialLinesFieldSpecification' => 'DifferentialFieldSpecification',
'DifferentialLintFieldSpecification' => 'DifferentialFieldSpecification',
'DifferentialLocalCommitsView' => 'AphrontView',
'DifferentialManiphestTasksFieldSpecification' => 'DifferentialFieldSpecification',
'DifferentialNewDiffMail' => 'DifferentialReviewRequestMail',
'DifferentialPathFieldSpecification' => 'DifferentialFieldSpecification',
'DifferentialPrimaryPaneView' => 'AphrontView',
'DifferentialReplyHandler' => 'PhabricatorMailReplyHandler',
'DifferentialResultsTableView' => 'AphrontView',
'DifferentialRevertPlanFieldSpecification' => 'DifferentialFieldSpecification',
'DifferentialReviewRequestMail' => 'DifferentialMail',
'DifferentialReviewedByFieldSpecification' => 'DifferentialFieldSpecification',
'DifferentialReviewersFieldSpecification' => 'DifferentialFieldSpecification',
'DifferentialRevision' => 'DifferentialDAO',
'DifferentialRevisionCommentListView' => 'AphrontView',
'DifferentialRevisionCommentView' => 'AphrontView',
'DifferentialRevisionDetailView' => 'AphrontView',
'DifferentialRevisionEditController' => 'DifferentialController',
'DifferentialRevisionIDFieldParserTestCase' => 'PhabricatorTestCase',
'DifferentialRevisionIDFieldSpecification' => 'DifferentialFieldSpecification',
'DifferentialRevisionListController' => 'DifferentialController',
'DifferentialRevisionListView' => 'AphrontView',
'DifferentialRevisionStatsController' => 'DifferentialController',
'DifferentialRevisionStatsView' => 'AphrontView',
'DifferentialRevisionStatusFieldSpecification' => 'DifferentialFieldSpecification',
'DifferentialRevisionUpdateHistoryView' => 'AphrontView',
'DifferentialRevisionViewController' => 'DifferentialController',
'DifferentialSubscribeController' => 'DifferentialController',
'DifferentialSummaryFieldSpecification' => 'DifferentialFieldSpecification',
'DifferentialTestPlanFieldSpecification' => 'DifferentialFieldSpecification',
'DifferentialTitleFieldSpecification' => 'DifferentialFieldSpecification',
'DifferentialUnitFieldSpecification' => 'DifferentialFieldSpecification',
'DiffusionBranchTableController' => 'DiffusionController',
'DiffusionBranchTableView' => 'DiffusionView',
'DiffusionBrowseController' => 'DiffusionController',
'DiffusionBrowseFileController' => 'DiffusionController',
'DiffusionBrowseTableView' => 'DiffusionView',
'DiffusionChangeController' => 'DiffusionController',
'DiffusionCommentListView' => 'AphrontView',
'DiffusionCommentView' => 'AphrontView',
'DiffusionCommitChangeTableView' => 'DiffusionView',
'DiffusionCommitController' => 'DiffusionController',
'DiffusionCommitParentsQuery' => 'DiffusionQuery',
'DiffusionCommitTagsQuery' => 'DiffusionQuery',
'DiffusionContainsQuery' => 'DiffusionQuery',
'DiffusionController' => 'PhabricatorController',
'DiffusionDiffController' => 'DiffusionController',
'DiffusionDiffQuery' => 'DiffusionQuery',
'DiffusionEmptyResultView' => 'DiffusionView',
'DiffusionExternalController' => 'DiffusionController',
'DiffusionFileContentQuery' => 'DiffusionQuery',
'DiffusionGitBranchQuery' => 'DiffusionBranchQuery',
'DiffusionGitBranchQueryTestCase' => 'PhabricatorTestCase',
'DiffusionGitBrowseQuery' => 'DiffusionBrowseQuery',
'DiffusionGitCommitParentsQuery' => 'DiffusionCommitParentsQuery',
'DiffusionGitCommitTagsQuery' => 'DiffusionCommitTagsQuery',
'DiffusionGitContainsQuery' => 'DiffusionContainsQuery',
'DiffusionGitDiffQuery' => 'DiffusionDiffQuery',
'DiffusionGitFileContentQuery' => 'DiffusionFileContentQuery',
'DiffusionGitHistoryQuery' => 'DiffusionHistoryQuery',
'DiffusionGitLastModifiedQuery' => 'DiffusionLastModifiedQuery',
'DiffusionGitMergedCommitsQuery' => 'DiffusionMergedCommitsQuery',
'DiffusionGitRawDiffQuery' => 'DiffusionRawDiffQuery',
'DiffusionGitRenameHistoryQuery' => 'DiffusionRenameHistoryQuery',
'DiffusionGitRequest' => 'DiffusionRequest',
'DiffusionGitTagListQuery' => 'DiffusionTagListQuery',
'DiffusionHistoryController' => 'DiffusionController',
'DiffusionHistoryQuery' => 'DiffusionQuery',
'DiffusionHistoryTableView' => 'DiffusionView',
'DiffusionHomeController' => 'DiffusionController',
'DiffusionInlineCommentController' => 'PhabricatorInlineCommentController',
'DiffusionLastModifiedController' => 'DiffusionController',
'DiffusionLastModifiedQuery' => 'DiffusionQuery',
'DiffusionMercurialBranchQuery' => 'DiffusionBranchQuery',
'DiffusionMercurialBrowseQuery' => 'DiffusionBrowseQuery',
'DiffusionMercurialCommitParentsQuery' => 'DiffusionCommitParentsQuery',
'DiffusionMercurialCommitTagsQuery' => 'DiffusionCommitTagsQuery',
'DiffusionMercurialContainsQuery' => 'DiffusionContainsQuery',
'DiffusionMercurialDiffQuery' => 'DiffusionDiffQuery',
'DiffusionMercurialFileContentQuery' => 'DiffusionFileContentQuery',
'DiffusionMercurialHistoryQuery' => 'DiffusionHistoryQuery',
'DiffusionMercurialLastModifiedQuery' => 'DiffusionLastModifiedQuery',
'DiffusionMercurialMergedCommitsQuery' => 'DiffusionMergedCommitsQuery',
'DiffusionMercurialRawDiffQuery' => 'DiffusionRawDiffQuery',
'DiffusionMercurialRenameHistoryQuery' => 'DiffusionRenameHistoryQuery',
'DiffusionMercurialRequest' => 'DiffusionRequest',
'DiffusionMercurialTagListQuery' => 'DiffusionTagListQuery',
'DiffusionMergedCommitsQuery' => 'DiffusionQuery',
'DiffusionPathCompleteController' => 'DiffusionController',
'DiffusionPathQueryTestCase' => 'PhabricatorTestCase',
'DiffusionPathValidateController' => 'DiffusionController',
'DiffusionRawDiffQuery' => 'DiffusionQuery',
'DiffusionRenameHistoryQuery' => 'DiffusionQuery',
'DiffusionRepositoryController' => 'DiffusionController',
'DiffusionSetupException' => 'AphrontUsageException',
'DiffusionSvnBrowseQuery' => 'DiffusionBrowseQuery',
'DiffusionSvnCommitParentsQuery' => 'DiffusionCommitParentsQuery',
'DiffusionSvnCommitTagsQuery' => 'DiffusionCommitTagsQuery',
'DiffusionSvnContainsQuery' => 'DiffusionContainsQuery',
'DiffusionSvnDiffQuery' => 'DiffusionDiffQuery',
'DiffusionSvnFileContentQuery' => 'DiffusionFileContentQuery',
'DiffusionSvnHistoryQuery' => 'DiffusionHistoryQuery',
'DiffusionSvnLastModifiedQuery' => 'DiffusionLastModifiedQuery',
'DiffusionSvnMergedCommitsQuery' => 'DiffusionMergedCommitsQuery',
'DiffusionSvnRawDiffQuery' => 'DiffusionRawDiffQuery',
'DiffusionSvnRenameHistoryQuery' => 'DiffusionRenameHistoryQuery',
'DiffusionSvnRequest' => 'DiffusionRequest',
'DiffusionSvnTagListQuery' => 'DiffusionTagListQuery',
'DiffusionSymbolController' => 'DiffusionController',
'DiffusionTagListController' => 'DiffusionController',
'DiffusionTagListQuery' => 'DiffusionQuery',
'DiffusionTagListView' => 'DiffusionView',
'DiffusionURITestCase' => 'ArcanistPhutilTestCase',
'DiffusionView' => 'AphrontView',
'DrydockAllocatorWorker' => 'PhabricatorWorker',
'DrydockApacheWebrootBlueprint' => 'DrydockBlueprint',
'DrydockApacheWebrootInterface' => 'DrydockWebrootInterface',
'DrydockCommandInterface' => 'DrydockInterface',
'DrydockController' => 'PhabricatorController',
'DrydockDAO' => 'PhabricatorLiskDAO',
'DrydockEC2HostBlueprint' => 'DrydockRemoteHostBlueprint',
'DrydockLease' => 'DrydockDAO',
'DrydockLeaseListController' => 'DrydockController',
'DrydockLeaseStatus' => 'DrydockConstants',
'DrydockLocalCommandInterface' => 'DrydockCommandInterface',
'DrydockLocalHostBlueprint' => 'DrydockBlueprint',
'DrydockLog' => 'DrydockDAO',
'DrydockLogController' => 'DrydockController',
'DrydockLogQuery' => 'PhabricatorOffsetPagedQuery',
'DrydockPhabricatorApplicationBlueprint' => 'DrydockBlueprint',
'DrydockRemoteHostBlueprint' => 'DrydockBlueprint',
'DrydockResource' => 'DrydockDAO',
'DrydockResourceAllocateController' => 'DrydockController',
'DrydockResourceListController' => 'DrydockController',
'DrydockResourceStatus' => 'DrydockConstants',
'DrydockSSHCommandInterface' => 'DrydockCommandInterface',
'DrydockWebrootInterface' => 'DrydockInterface',
'HarbormasterDAO' => 'PhabricatorLiskDAO',
'HarbormasterScratchTable' => 'HarbormasterDAO',
'HeraldAction' => 'HeraldDAO',
'HeraldApplyTranscript' => 'HeraldDAO',
'HeraldCommitAdapter' => 'HeraldObjectAdapter',
'HeraldCondition' => 'HeraldDAO',
'HeraldController' => 'PhabricatorController',
'HeraldDAO' => 'PhabricatorLiskDAO',
'HeraldDeleteController' => 'HeraldController',
'HeraldDifferentialRevisionAdapter' => 'HeraldObjectAdapter',
'HeraldDryRunAdapter' => 'HeraldObjectAdapter',
'HeraldEditLogQuery' => 'PhabricatorOffsetPagedQuery',
'HeraldHomeController' => 'HeraldController',
'HeraldNewController' => 'HeraldController',
'HeraldRule' => 'HeraldDAO',
'HeraldRuleController' => 'HeraldController',
'HeraldRuleEdit' => 'HeraldDAO',
'HeraldRuleEditHistoryController' => 'HeraldController',
'HeraldRuleEditHistoryView' => 'AphrontView',
'HeraldRuleListView' => 'AphrontView',
'HeraldRuleQuery' => 'PhabricatorOffsetPagedQuery',
'HeraldTestConsoleController' => 'HeraldController',
'HeraldTranscript' => 'HeraldDAO',
'HeraldTranscriptController' => 'HeraldController',
'HeraldTranscriptListController' => 'HeraldController',
'JavelinReactorExample' => 'PhabricatorUIExample',
'JavelinViewExample' => 'PhabricatorUIExample',
'JavelinViewExampleServerView' => 'AphrontView',
'LiskFixtureTestCase' => 'PhabricatorTestCase',
'LiskIsolationTestCase' => 'PhabricatorTestCase',
'LiskIsolationTestDAO' => 'LiskDAO',
'ManiphestAction' => 'PhrictionConstants',
'ManiphestAuxiliaryFieldDefaultSpecification' => 'ManiphestAuxiliaryFieldSpecification',
'ManiphestBatchEditController' => 'ManiphestController',
'ManiphestController' => 'PhabricatorController',
'ManiphestDAO' => 'PhabricatorLiskDAO',
'ManiphestDefaultTaskExtensions' => 'ManiphestTaskExtensions',
'ManiphestExportController' => 'ManiphestController',
'ManiphestReplyHandler' => 'PhabricatorMailReplyHandler',
'ManiphestReportController' => 'ManiphestController',
'ManiphestSavedQuery' => 'ManiphestDAO',
'ManiphestSavedQueryDeleteController' => 'ManiphestController',
'ManiphestSavedQueryEditController' => 'ManiphestController',
'ManiphestSavedQueryListController' => 'ManiphestController',
'ManiphestSubpriorityController' => 'ManiphestController',
'ManiphestTask' => 'ManiphestDAO',
'ManiphestTaskAuxiliaryStorage' => 'ManiphestDAO',
'ManiphestTaskDescriptionChangeController' => 'ManiphestController',
'ManiphestTaskDescriptionPreviewController' => 'ManiphestController',
'ManiphestTaskDetailController' => 'ManiphestController',
'ManiphestTaskEditController' => 'ManiphestController',
'ManiphestTaskListController' => 'ManiphestController',
'ManiphestTaskListView' => 'ManiphestView',
'ManiphestTaskOwner' => 'ManiphestConstants',
'ManiphestTaskPriority' => 'ManiphestConstants',
'ManiphestTaskProject' => 'ManiphestDAO',
'ManiphestTaskProjectsView' => 'ManiphestView',
'ManiphestTaskStatus' => 'ManiphestConstants',
'ManiphestTaskSubscriber' => 'ManiphestDAO',
'ManiphestTaskSummaryView' => 'ManiphestView',
'ManiphestTransaction' => 'ManiphestDAO',
'ManiphestTransactionDetailView' => 'ManiphestView',
'ManiphestTransactionListView' => 'ManiphestView',
'ManiphestTransactionPreviewController' => 'ManiphestController',
'ManiphestTransactionSaveController' => 'ManiphestController',
'ManiphestTransactionType' => 'ManiphestConstants',
'ManiphestView' => 'AphrontView',
'MetaMTANotificationType' => 'MetaMTAConstants',
'OwnersPackageReplyHandler' => 'PhabricatorMailReplyHandler',
'PackageCreateMail' => 'PackageMail',
'PackageDeleteMail' => 'PackageMail',
'PackageModifyMail' => 'PackageMail',
'Phabricator404Controller' => 'PhabricatorController',
'PhabricatorAphlictTestPageController' => 'PhabricatorNotificationsController',
'PhabricatorAuditAddCommentController' => 'PhabricatorAuditController',
'PhabricatorAuditComment' => 'PhabricatorAuditDAO',
'PhabricatorAuditCommitListView' => 'AphrontView',
'PhabricatorAuditController' => 'PhabricatorController',
'PhabricatorAuditDAO' => 'PhabricatorLiskDAO',
'PhabricatorAuditInlineComment' => 'PhabricatorAuditDAO',
'PhabricatorAuditListController' => 'PhabricatorAuditController',
'PhabricatorAuditListView' => 'AphrontView',
'PhabricatorAuditPreviewController' => 'PhabricatorAuditController',
'PhabricatorAuditReplyHandler' => 'PhabricatorMailReplyHandler',
'PhabricatorAuthController' => 'PhabricatorController',
'PhabricatorBuiltinPatchList' => 'PhabricatorSQLPatchList',
'PhabricatorCalendarBrowseController' => 'PhabricatorCalendarController',
'PhabricatorCalendarController' => 'PhabricatorController',
'PhabricatorCalendarDAO' => 'PhabricatorLiskDAO',
'PhabricatorCalendarHoliday' => 'PhabricatorCalendarDAO',
'PhabricatorCalendarHolidayTestCase' => 'PhabricatorTestCase',
'PhabricatorChangesetResponse' => 'AphrontProxyResponse',
'PhabricatorChatLogChannelListController' => 'PhabricatorChatLogController',
'PhabricatorChatLogChannelLogController' => 'PhabricatorChatLogController',
'PhabricatorChatLogController' => 'PhabricatorController',
'PhabricatorChatLogDAO' => 'PhabricatorLiskDAO',
'PhabricatorChatLogEvent' => 'PhabricatorChatLogDAO',
'PhabricatorChatLogEventType' => 'PhabricatorChatLogConstants',
'PhabricatorChatLogQuery' => 'PhabricatorOffsetPagedQuery',
'PhabricatorConduitAPIController' => 'PhabricatorConduitController',
'PhabricatorConduitCertificateToken' => 'PhabricatorConduitDAO',
'PhabricatorConduitConnectionLog' => 'PhabricatorConduitDAO',
'PhabricatorConduitConsoleController' => 'PhabricatorConduitController',
'PhabricatorConduitController' => 'PhabricatorController',
'PhabricatorConduitDAO' => 'PhabricatorLiskDAO',
'PhabricatorConduitListController' => 'PhabricatorConduitController',
'PhabricatorConduitLogController' => 'PhabricatorConduitController',
'PhabricatorConduitMethodCallLog' => 'PhabricatorConduitDAO',
'PhabricatorConduitTokenController' => 'PhabricatorConduitController',
'PhabricatorContentSourceView' => 'AphrontView',
'PhabricatorController' => 'AphrontController',
'PhabricatorCountdownController' => 'PhabricatorController',
'PhabricatorCountdownDAO' => 'PhabricatorLiskDAO',
'PhabricatorCountdownDeleteController' => 'PhabricatorCountdownController',
'PhabricatorCountdownEditController' => 'PhabricatorCountdownController',
'PhabricatorCountdownListController' => 'PhabricatorCountdownController',
'PhabricatorCountdownViewController' => 'PhabricatorCountdownController',
'PhabricatorDaemon' => 'PhutilDaemon',
'PhabricatorDaemonCombinedLogController' => 'PhabricatorDaemonController',
'PhabricatorDaemonConsoleController' => 'PhabricatorDaemonController',
'PhabricatorDaemonController' => 'PhabricatorController',
'PhabricatorDaemonDAO' => 'PhabricatorLiskDAO',
'PhabricatorDaemonLog' => 'PhabricatorDaemonDAO',
'PhabricatorDaemonLogEvent' => 'PhabricatorDaemonDAO',
'PhabricatorDaemonLogEventsView' => 'AphrontView',
'PhabricatorDaemonLogListController' => 'PhabricatorDaemonController',
'PhabricatorDaemonLogListView' => 'AphrontView',
'PhabricatorDaemonLogViewController' => 'PhabricatorDaemonController',
'PhabricatorDaemonTimelineConsoleController' => 'PhabricatorDaemonController',
'PhabricatorDaemonTimelineEventController' => 'PhabricatorDaemonController',
'PhabricatorDefaultFileStorageEngineSelector' => 'PhabricatorFileStorageEngineSelector',
'PhabricatorDefaultSearchEngineSelector' => 'PhabricatorSearchEngineSelector',
'PhabricatorDirectoryController' => 'PhabricatorController',
'PhabricatorDirectoryMainController' => 'PhabricatorDirectoryController',
'PhabricatorDisabledUserController' => 'PhabricatorAuthController',
'PhabricatorDraft' => 'PhabricatorDraftDAO',
'PhabricatorDraftDAO' => 'PhabricatorLiskDAO',
'PhabricatorEdgeConfig' => 'PhabricatorEdgeConstants',
'PhabricatorEdgeQuery' => 'PhabricatorQuery',
'PhabricatorEmailLoginController' => 'PhabricatorAuthController',
'PhabricatorEmailTokenController' => 'PhabricatorAuthController',
'PhabricatorEmailVerificationController' => 'PhabricatorPeopleController',
'PhabricatorEnvTestCase' => 'PhabricatorTestCase',
'PhabricatorErrorExample' => 'PhabricatorUIExample',
'PhabricatorEvent' => 'PhutilEvent',
'PhabricatorEventType' => 'PhutilEventType',
'PhabricatorFeedController' => 'PhabricatorController',
'PhabricatorFeedDAO' => 'PhabricatorLiskDAO',
'PhabricatorFeedPublicStreamController' => 'PhabricatorFeedController',
'PhabricatorFeedStoryAudit' => 'PhabricatorFeedStory',
'PhabricatorFeedStoryData' => 'PhabricatorFeedDAO',
'PhabricatorFeedStoryDifferential' => 'PhabricatorFeedStory',
'PhabricatorFeedStoryManiphest' => 'PhabricatorFeedStory',
'PhabricatorFeedStoryPhriction' => 'PhabricatorFeedStory',
'PhabricatorFeedStoryProject' => 'PhabricatorFeedStory',
'PhabricatorFeedStoryReference' => 'PhabricatorFeedDAO',
'PhabricatorFeedStoryStatus' => 'PhabricatorFeedStory',
'PhabricatorFeedStoryTypeConstants' => 'PhabricatorFeedConstants',
'PhabricatorFeedStoryUnknown' => 'PhabricatorFeedStory',
'PhabricatorFeedStoryView' => 'PhabricatorFeedView',
'PhabricatorFeedView' => 'AphrontView',
'PhabricatorFile' => 'PhabricatorFileDAO',
'PhabricatorFileController' => 'PhabricatorController',
'PhabricatorFileDAO' => 'PhabricatorLiskDAO',
'PhabricatorFileDataController' => 'PhabricatorFileController',
'PhabricatorFileDeleteController' => 'PhabricatorFileController',
'PhabricatorFileDropUploadController' => 'PhabricatorFileController',
'PhabricatorFileImageMacro' => 'PhabricatorFileDAO',
'PhabricatorFileInfoController' => 'PhabricatorFileController',
'PhabricatorFileListController' => 'PhabricatorFileController',
'PhabricatorFileMacroDeleteController' => 'PhabricatorFileController',
'PhabricatorFileMacroEditController' => 'PhabricatorFileController',
'PhabricatorFileMacroListController' => 'PhabricatorFileController',
'PhabricatorFileProxyController' => 'PhabricatorFileController',
'PhabricatorFileProxyImage' => 'PhabricatorFileDAO',
'PhabricatorFileShortcutController' => 'PhabricatorFileController',
'PhabricatorFileSideNavView' => 'AphrontView',
'PhabricatorFileStorageBlob' => 'PhabricatorFileDAO',
'PhabricatorFileTransformController' => 'PhabricatorFileController',
'PhabricatorFileUploadController' => 'PhabricatorFileController',
'PhabricatorFileUploadView' => 'AphrontView',
'PhabricatorFlag' => 'PhabricatorFlagDAO',
'PhabricatorFlagColor' => 'PhabricatorFlagConstants',
'PhabricatorFlagController' => 'PhabricatorController',
'PhabricatorFlagDAO' => 'PhabricatorLiskDAO',
'PhabricatorFlagDeleteController' => 'PhabricatorFlagController',
'PhabricatorFlagEditController' => 'PhabricatorFlagController',
'PhabricatorFlagListController' => 'PhabricatorFlagController',
'PhabricatorFlagListView' => 'AphrontView',
'PhabricatorFormExample' => 'PhabricatorUIExample',
'PhabricatorGarbageCollectorDaemon' => 'PhabricatorDaemon',
'PhabricatorGoodForNothingWorker' => 'PhabricatorWorker',
'PhabricatorHelpController' => 'PhabricatorController',
'PhabricatorHelpKeyboardShortcutController' => 'PhabricatorHelpController',
'PhabricatorIDPagedPolicyQuery' => 'PhabricatorPolicyQuery',
'PhabricatorIRCBot' => 'PhabricatorDaemon',
'PhabricatorIRCDifferentialNotificationHandler' => 'PhabricatorIRCHandler',
'PhabricatorIRCLogHandler' => 'PhabricatorIRCHandler',
'PhabricatorIRCMacroHandler' => 'PhabricatorIRCHandler',
'PhabricatorIRCObjectNameHandler' => 'PhabricatorIRCHandler',
'PhabricatorIRCProtocolHandler' => 'PhabricatorIRCHandler',
'PhabricatorIRCWhatsNewHandler' => 'PhabricatorIRCHandler',
'PhabricatorInfrastructureTestCase' => 'PhabricatorTestCase',
'PhabricatorInlineCommentController' => 'PhabricatorController',
'PhabricatorInlineSummaryView' => 'AphrontView',
'PhabricatorJavelinLinter' => 'ArcanistLinter',
'PhabricatorLintEngine' => 'PhutilLintEngine',
'PhabricatorLiskDAO' => 'LiskDAO',
'PhabricatorLocalDiskFileStorageEngine' => 'PhabricatorFileStorageEngine',
'PhabricatorLocalTimeTestCase' => 'PhabricatorTestCase',
'PhabricatorLoginController' => 'PhabricatorAuthController',
'PhabricatorLoginValidateController' => 'PhabricatorAuthController',
'PhabricatorLogoutController' => 'PhabricatorAuthController',
'PhabricatorMailImplementationAmazonSESAdapter' => 'PhabricatorMailImplementationPHPMailerLiteAdapter',
'PhabricatorMailImplementationPHPMailerLiteAdapter' => 'PhabricatorMailImplementationAdapter',
'PhabricatorMailImplementationSendGridAdapter' => 'PhabricatorMailImplementationAdapter',
'PhabricatorMailImplementationTestAdapter' => 'PhabricatorMailImplementationAdapter',
'PhabricatorMetaMTAController' => 'PhabricatorController',
'PhabricatorMetaMTADAO' => 'PhabricatorLiskDAO',
'PhabricatorMetaMTAEmailBodyParserTestCase' => 'PhabricatorTestCase',
'PhabricatorMetaMTAListController' => 'PhabricatorMetaMTAController',
'PhabricatorMetaMTAMail' => 'PhabricatorMetaMTADAO',
'PhabricatorMetaMTAMailTestCase' => 'PhabricatorTestCase',
'PhabricatorMetaMTAMailingList' => 'PhabricatorMetaMTADAO',
'PhabricatorMetaMTAMailingListEditController' => 'PhabricatorMetaMTAController',
'PhabricatorMetaMTAMailingListsController' => 'PhabricatorMetaMTAController',
'PhabricatorMetaMTAReceiveController' => 'PhabricatorMetaMTAController',
'PhabricatorMetaMTAReceivedListController' => 'PhabricatorMetaMTAController',
'PhabricatorMetaMTAReceivedMail' => 'PhabricatorMetaMTADAO',
'PhabricatorMetaMTASendController' => 'PhabricatorMetaMTAController',
'PhabricatorMetaMTASendGridReceiveController' => 'PhabricatorMetaMTAController',
'PhabricatorMetaMTAViewController' => 'PhabricatorMetaMTAController',
'PhabricatorMetaMTAWorker' => 'PhabricatorWorker',
'PhabricatorMustVerifyEmailController' => 'PhabricatorAuthController',
'PhabricatorMySQLFileStorageEngine' => 'PhabricatorFileStorageEngine',
'PhabricatorNotificationsController' => 'PhabricatorController',
'PhabricatorOAuthClientAuthorization' => 'PhabricatorOAuthServerDAO',
'PhabricatorOAuthClientAuthorizationBaseController' => 'PhabricatorOAuthServerController',
'PhabricatorOAuthClientAuthorizationDeleteController' => 'PhabricatorOAuthClientAuthorizationBaseController',
'PhabricatorOAuthClientAuthorizationEditController' => 'PhabricatorOAuthClientAuthorizationBaseController',
'PhabricatorOAuthClientAuthorizationListController' => 'PhabricatorOAuthClientAuthorizationBaseController',
'PhabricatorOAuthClientAuthorizationQuery' => 'PhabricatorOffsetPagedQuery',
'PhabricatorOAuthClientBaseController' => 'PhabricatorOAuthServerController',
'PhabricatorOAuthClientDeleteController' => 'PhabricatorOAuthClientBaseController',
'PhabricatorOAuthClientEditController' => 'PhabricatorOAuthClientBaseController',
'PhabricatorOAuthClientListController' => 'PhabricatorOAuthClientBaseController',
'PhabricatorOAuthClientViewController' => 'PhabricatorOAuthClientBaseController',
'PhabricatorOAuthDefaultRegistrationController' => 'PhabricatorOAuthRegistrationController',
'PhabricatorOAuthDiagnosticsController' => 'PhabricatorAuthController',
'PhabricatorOAuthFailureView' => 'AphrontView',
'PhabricatorOAuthLoginController' => 'PhabricatorAuthController',
'PhabricatorOAuthProviderDisqus' => 'PhabricatorOAuthProvider',
'PhabricatorOAuthProviderFacebook' => 'PhabricatorOAuthProvider',
'PhabricatorOAuthProviderGitHub' => 'PhabricatorOAuthProvider',
'PhabricatorOAuthProviderGoogle' => 'PhabricatorOAuthProvider',
'PhabricatorOAuthProviderPhabricator' => 'PhabricatorOAuthProvider',
'PhabricatorOAuthRegistrationController' => 'PhabricatorAuthController',
'PhabricatorOAuthResponse' => 'AphrontResponse',
'PhabricatorOAuthServerAccessToken' => 'PhabricatorOAuthServerDAO',
'PhabricatorOAuthServerAuthController' => 'PhabricatorAuthController',
'PhabricatorOAuthServerAuthorizationCode' => 'PhabricatorOAuthServerDAO',
'PhabricatorOAuthServerClient' => 'PhabricatorOAuthServerDAO',
'PhabricatorOAuthServerClientQuery' => 'PhabricatorOffsetPagedQuery',
'PhabricatorOAuthServerController' => 'PhabricatorController',
'PhabricatorOAuthServerDAO' => 'PhabricatorLiskDAO',
'PhabricatorOAuthServerTestCase' => 'PhabricatorTestCase',
'PhabricatorOAuthServerTestController' => 'PhabricatorOAuthServerController',
'PhabricatorOAuthServerTokenController' => 'PhabricatorAuthController',
'PhabricatorOAuthUnlinkController' => 'PhabricatorAuthController',
'PhabricatorObjectGraph' => 'AbstractDirectedGraph',
'PhabricatorObjectHandleStatus' => 'PhabricatorObjectHandleConstants',
'PhabricatorOffsetPagedQuery' => 'PhabricatorQuery',
'PhabricatorOwnersController' => 'PhabricatorController',
'PhabricatorOwnersDAO' => 'PhabricatorLiskDAO',
'PhabricatorOwnersDeleteController' => 'PhabricatorOwnersController',
'PhabricatorOwnersDetailController' => 'PhabricatorOwnersController',
'PhabricatorOwnersEditController' => 'PhabricatorOwnersController',
'PhabricatorOwnersListController' => 'PhabricatorOwnersController',
'PhabricatorOwnersOwner' => 'PhabricatorOwnersDAO',
'PhabricatorOwnersPackage' => 'PhabricatorOwnersDAO',
'PhabricatorOwnersPath' => 'PhabricatorOwnersDAO',
'PhabricatorPHIDController' => 'PhabricatorController',
'PhabricatorPHIDLookupController' => 'PhabricatorPHIDController',
'PhabricatorPaste' => 'PhabricatorPasteDAO',
'PhabricatorPasteController' => 'PhabricatorController',
'PhabricatorPasteDAO' => 'PhabricatorLiskDAO',
'PhabricatorPasteListController' => 'PhabricatorPasteController',
'PhabricatorPasteQuery' => 'PhabricatorIDPagedPolicyQuery',
'PhabricatorPasteViewController' => 'PhabricatorPasteController',
'PhabricatorPeopleController' => 'PhabricatorController',
'PhabricatorPeopleEditController' => 'PhabricatorPeopleController',
'PhabricatorPeopleListController' => 'PhabricatorPeopleController',
'PhabricatorPeopleLogsController' => 'PhabricatorPeopleController',
'PhabricatorPeopleProfileController' => 'PhabricatorPeopleController',
'PhabricatorPeopleQuery' => 'PhabricatorOffsetPagedQuery',
'PhabricatorPolicies' => 'PhabricatorPolicyConstants',
'PhabricatorPolicyCapability' => 'PhabricatorPolicyConstants',
'PhabricatorPolicyQuery' => 'PhabricatorQuery',
'PhabricatorPolicyTestCase' => 'PhabricatorTestCase',
'PhabricatorPolicyTestQuery' => 'PhabricatorPolicyQuery',
'PhabricatorProfileHeaderView' => 'AphrontView',
'PhabricatorProject' => 'PhabricatorProjectDAO',
'PhabricatorProjectAffiliation' => 'PhabricatorProjectDAO',
'PhabricatorProjectController' => 'PhabricatorController',
'PhabricatorProjectCreateController' => 'PhabricatorProjectController',
'PhabricatorProjectDAO' => 'PhabricatorLiskDAO',
'PhabricatorProjectListController' => 'PhabricatorProjectController',
'PhabricatorProjectProfile' => 'PhabricatorProjectDAO',
'PhabricatorProjectProfileController' => 'PhabricatorProjectController',
'PhabricatorProjectProfileEditController' => 'PhabricatorProjectController',
'PhabricatorProjectSubproject' => 'PhabricatorProjectDAO',
'PhabricatorProjectTransaction' => 'PhabricatorProjectDAO',
'PhabricatorProjectTransactionType' => 'PhabricatorProjectConstants',
'PhabricatorProjectUpdateController' => 'PhabricatorProjectController',
'PhabricatorRedirectController' => 'PhabricatorController',
'PhabricatorRefreshCSRFController' => 'PhabricatorAuthController',
'PhabricatorRemarkupRuleDifferential' => 'PhabricatorRemarkupRuleObjectName',
'PhabricatorRemarkupRuleDifferentialHandle' => 'PhabricatorRemarkupRuleObjectHandle',
'PhabricatorRemarkupRuleDiffusion' => 'PhutilRemarkupRule',
'PhabricatorRemarkupRuleEmbedFile' => 'PhutilRemarkupRule',
'PhabricatorRemarkupRuleImageMacro' => 'PhutilRemarkupRule',
'PhabricatorRemarkupRuleManiphest' => 'PhabricatorRemarkupRuleObjectName',
'PhabricatorRemarkupRuleManiphestHandle' => 'PhabricatorRemarkupRuleObjectHandle',
'PhabricatorRemarkupRuleMention' => 'PhutilRemarkupRule',
'PhabricatorRemarkupRuleObjectHandle' => 'PhutilRemarkupRule',
'PhabricatorRemarkupRuleObjectName' => 'PhutilRemarkupRule',
'PhabricatorRemarkupRulePaste' => 'PhabricatorRemarkupRuleObjectName',
'PhabricatorRemarkupRulePhriction' => 'PhutilRemarkupRule',
'PhabricatorRemarkupRuleProxyImage' => 'PhutilRemarkupRule',
'PhabricatorRemarkupRuleYoutube' => 'PhutilRemarkupRule',
'PhabricatorRepository' => 'PhabricatorRepositoryDAO',
'PhabricatorRepositoryArcanistProject' => 'PhabricatorRepositoryDAO',
'PhabricatorRepositoryArcanistProjectEditController' => 'PhabricatorRepositoryController',
'PhabricatorRepositoryAuditRequest' => 'PhabricatorRepositoryDAO',
'PhabricatorRepositoryCommit' => 'PhabricatorRepositoryDAO',
'PhabricatorRepositoryCommitChangeParserWorker' => 'PhabricatorRepositoryCommitParserWorker',
'PhabricatorRepositoryCommitData' => 'PhabricatorRepositoryDAO',
'PhabricatorRepositoryCommitHeraldWorker' => 'PhabricatorRepositoryCommitParserWorker',
'PhabricatorRepositoryCommitMessageParserWorker' => 'PhabricatorRepositoryCommitParserWorker',
'PhabricatorRepositoryCommitOwnersWorker' => 'PhabricatorRepositoryCommitParserWorker',
'PhabricatorRepositoryCommitParserWorker' => 'PhabricatorWorker',
'PhabricatorRepositoryController' => 'PhabricatorController',
'PhabricatorRepositoryCreateController' => 'PhabricatorRepositoryController',
'PhabricatorRepositoryDAO' => 'PhabricatorLiskDAO',
'PhabricatorRepositoryDefaultCommitMessageDetailParser' => 'PhabricatorRepositoryCommitMessageDetailParser',
'PhabricatorRepositoryDeleteController' => 'PhabricatorRepositoryController',
'PhabricatorRepositoryEditController' => 'PhabricatorRepositoryController',
'PhabricatorRepositoryGitCommitChangeParserWorker' => 'PhabricatorRepositoryCommitChangeParserWorker',
'PhabricatorRepositoryGitCommitMessageParserWorker' => 'PhabricatorRepositoryCommitMessageParserWorker',
'PhabricatorRepositoryListController' => 'PhabricatorRepositoryController',
'PhabricatorRepositoryMercurialCommitChangeParserWorker' => 'PhabricatorRepositoryCommitChangeParserWorker',
'PhabricatorRepositoryMercurialCommitMessageParserWorker' => 'PhabricatorRepositoryCommitMessageParserWorker',
'PhabricatorRepositoryPullLocalDaemon' => 'PhabricatorDaemon',
'PhabricatorRepositoryPullLocalDaemonTestCase' => 'PhabricatorTestCase',
'PhabricatorRepositoryShortcut' => 'PhabricatorRepositoryDAO',
'PhabricatorRepositorySvnCommitChangeParserWorker' => 'PhabricatorRepositoryCommitChangeParserWorker',
'PhabricatorRepositorySvnCommitMessageParserWorker' => 'PhabricatorRepositoryCommitMessageParserWorker',
'PhabricatorRepositorySymbol' => 'PhabricatorRepositoryDAO',
'PhabricatorRepositoryTestCase' => 'PhabricatorTestCase',
'PhabricatorS3FileStorageEngine' => 'PhabricatorFileStorageEngine',
'PhabricatorSearchAttachController' => 'PhabricatorSearchBaseController',
'PhabricatorSearchBaseController' => 'PhabricatorController',
'PhabricatorSearchCommitIndexer' => 'PhabricatorSearchDocumentIndexer',
'PhabricatorSearchController' => 'PhabricatorSearchBaseController',
'PhabricatorSearchDAO' => 'PhabricatorLiskDAO',
'PhabricatorSearchDifferentialIndexer' => 'PhabricatorSearchDocumentIndexer',
'PhabricatorSearchDocument' => 'PhabricatorSearchDAO',
'PhabricatorSearchDocumentField' => 'PhabricatorSearchDAO',
'PhabricatorSearchDocumentRelationship' => 'PhabricatorSearchDAO',
'PhabricatorSearchEngineElastic' => 'PhabricatorSearchEngine',
'PhabricatorSearchEngineMySQL' => 'PhabricatorSearchEngine',
'PhabricatorSearchIndexController' => 'PhabricatorSearchBaseController',
'PhabricatorSearchManiphestIndexer' => 'PhabricatorSearchDocumentIndexer',
'PhabricatorSearchPhrictionIndexer' => 'PhabricatorSearchDocumentIndexer',
'PhabricatorSearchQuery' => 'PhabricatorSearchDAO',
'PhabricatorSearchResultView' => 'AphrontView',
'PhabricatorSearchSelectController' => 'PhabricatorSearchBaseController',
'PhabricatorSearchUserIndexer' => 'PhabricatorSearchDocumentIndexer',
'PhabricatorSlowvoteChoice' => 'PhabricatorSlowvoteDAO',
'PhabricatorSlowvoteComment' => 'PhabricatorSlowvoteDAO',
'PhabricatorSlowvoteController' => 'PhabricatorController',
'PhabricatorSlowvoteCreateController' => 'PhabricatorSlowvoteController',
'PhabricatorSlowvoteDAO' => 'PhabricatorLiskDAO',
'PhabricatorSlowvoteListController' => 'PhabricatorSlowvoteController',
'PhabricatorSlowvoteOption' => 'PhabricatorSlowvoteDAO',
'PhabricatorSlowvotePoll' => 'PhabricatorSlowvoteDAO',
'PhabricatorSlowvotePollController' => 'PhabricatorSlowvoteController',
'PhabricatorSlugTestCase' => 'PhabricatorTestCase',
'PhabricatorSortTableExample' => 'PhabricatorUIExample',
'PhabricatorStandardPageView' => 'AphrontPageView',
'PhabricatorStatusController' => 'PhabricatorController',
'PhabricatorStorageManagementDatabasesWorkflow' => 'PhabricatorStorageManagementWorkflow',
'PhabricatorStorageManagementDestroyWorkflow' => 'PhabricatorStorageManagementWorkflow',
'PhabricatorStorageManagementDumpWorkflow' => 'PhabricatorStorageManagementWorkflow',
'PhabricatorStorageManagementStatusWorkflow' => 'PhabricatorStorageManagementWorkflow',
'PhabricatorStorageManagementUpgradeWorkflow' => 'PhabricatorStorageManagementWorkflow',
'PhabricatorStorageManagementWorkflow' => 'PhutilArgumentWorkflow',
'PhabricatorSymbolNameLinter' => 'ArcanistXHPASTLintNamingHook',
'PhabricatorTaskmasterDaemon' => 'PhabricatorDaemon',
'PhabricatorTestCase' => 'ArcanistPhutilTestCase',
'PhabricatorTimelineCursor' => 'PhabricatorTimelineDAO',
'PhabricatorTimelineDAO' => 'PhabricatorLiskDAO',
'PhabricatorTimelineEvent' => 'PhabricatorTimelineDAO',
'PhabricatorTimelineEventData' => 'PhabricatorTimelineDAO',
'PhabricatorTimer' => 'PhabricatorCountdownDAO',
'PhabricatorTransactionView' => 'AphrontView',
'PhabricatorTransformedFile' => 'PhabricatorFileDAO',
'PhabricatorTrivialTestCase' => 'PhabricatorTestCase',
'PhabricatorTypeaheadCommonDatasourceController' => 'PhabricatorTypeaheadDatasourceController',
'PhabricatorTypeaheadDatasourceController' => 'PhabricatorController',
'PhabricatorUIExampleController' => 'PhabricatorController',
'PhabricatorUIExampleRenderController' => 'PhabricatorUIExampleController',
'PhabricatorUIListFilterExample' => 'PhabricatorUIExample',
'PhabricatorUIPagerExample' => 'PhabricatorUIExample',
'PhabricatorUITooltipExample' => 'PhabricatorUIExample',
'PhabricatorUnitsTestCase' => 'PhabricatorTestCase',
'PhabricatorUser' => 'PhabricatorUserDAO',
'PhabricatorUserAccountSettingsPanelController' => 'PhabricatorUserSettingsPanelController',
'PhabricatorUserConduitSettingsPanelController' => 'PhabricatorUserSettingsPanelController',
'PhabricatorUserDAO' => 'PhabricatorLiskDAO',
'PhabricatorUserEmail' => 'PhabricatorUserDAO',
'PhabricatorUserEmailPreferenceSettingsPanelController' => 'PhabricatorUserSettingsPanelController',
'PhabricatorUserEmailSettingsPanelController' => 'PhabricatorUserSettingsPanelController',
'PhabricatorUserLog' => 'PhabricatorUserDAO',
'PhabricatorUserOAuthInfo' => 'PhabricatorUserDAO',
'PhabricatorUserOAuthSettingsPanelController' => 'PhabricatorUserSettingsPanelController',
'PhabricatorUserPasswordSettingsPanelController' => 'PhabricatorUserSettingsPanelController',
'PhabricatorUserPreferenceSettingsPanelController' => 'PhabricatorUserSettingsPanelController',
'PhabricatorUserPreferences' => 'PhabricatorUserDAO',
'PhabricatorUserProfile' => 'PhabricatorUserDAO',
'PhabricatorUserProfileSettingsPanelController' => 'PhabricatorUserSettingsPanelController',
'PhabricatorUserSSHKey' => 'PhabricatorUserDAO',
'PhabricatorUserSSHKeysSettingsPanelController' => 'PhabricatorUserSettingsPanelController',
'PhabricatorUserSearchSettingsPanelController' => 'PhabricatorUserSettingsPanelController',
'PhabricatorUserSettingsController' => 'PhabricatorPeopleController',
'PhabricatorUserSettingsPanelController' => 'PhabricatorPeopleController',
'PhabricatorUserStatus' => 'PhabricatorUserDAO',
'PhabricatorUserTestCase' => 'PhabricatorTestCase',
'PhabricatorWorkerDAO' => 'PhabricatorLiskDAO',
'PhabricatorWorkerTask' => 'PhabricatorWorkerDAO',
'PhabricatorWorkerTaskData' => 'PhabricatorWorkerDAO',
'PhabricatorWorkerTaskDetailController' => 'PhabricatorDaemonController',
'PhabricatorWorkerTaskUpdateController' => 'PhabricatorDaemonController',
'PhabricatorXHPASTViewController' => 'PhabricatorController',
'PhabricatorXHPASTViewDAO' => 'PhabricatorLiskDAO',
'PhabricatorXHPASTViewFrameController' => 'PhabricatorXHPASTViewController',
'PhabricatorXHPASTViewFramesetController' => 'PhabricatorXHPASTViewController',
'PhabricatorXHPASTViewInputController' => 'PhabricatorXHPASTViewPanelController',
'PhabricatorXHPASTViewPanelController' => 'PhabricatorXHPASTViewController',
'PhabricatorXHPASTViewParseTree' => 'PhabricatorXHPASTViewDAO',
'PhabricatorXHPASTViewRunController' => 'PhabricatorXHPASTViewController',
'PhabricatorXHPASTViewStreamController' => 'PhabricatorXHPASTViewPanelController',
'PhabricatorXHPASTViewTreeController' => 'PhabricatorXHPASTViewPanelController',
'PhabricatorXHProfController' => 'PhabricatorController',
'PhabricatorXHProfProfileController' => 'PhabricatorXHProfController',
'PhabricatorXHProfProfileSymbolView' => 'PhabricatorXHProfProfileView',
'PhabricatorXHProfProfileTopLevelView' => 'PhabricatorXHProfProfileView',
'PhabricatorXHProfProfileView' => 'AphrontView',
'PhameController' => 'PhabricatorController',
'PhameDAO' => 'PhabricatorLiskDAO',
'PhameDraftListController' => 'PhamePostListBaseController',
'PhamePost' => 'PhameDAO',
'PhamePostDeleteController' => 'PhameController',
'PhamePostDetailView' => 'AphrontView',
'PhamePostEditController' => 'PhameController',
'PhamePostListBaseController' => 'PhameController',
'PhamePostListController' => 'PhamePostListBaseController',
'PhamePostListView' => 'AphrontView',
'PhamePostPreviewController' => 'PhameController',
'PhamePostQuery' => 'PhabricatorOffsetPagedQuery',
'PhamePostViewController' => 'PhameController',
'PhortuneMonthYearExpiryControl' => 'AphrontFormControl',
'PhortuneStripeBaseController' => 'PhabricatorController',
'PhortuneStripePaymentFormView' => 'AphrontView',
'PhortuneStripeTestPaymentFormController' => 'PhortuneStripeBaseController',
'PhrictionActionConstants' => 'PhrictionConstants',
'PhrictionChangeType' => 'PhrictionConstants',
'PhrictionContent' => 'PhrictionDAO',
'PhrictionController' => 'PhabricatorController',
'PhrictionDAO' => 'PhabricatorLiskDAO',
'PhrictionDeleteController' => 'PhrictionController',
'PhrictionDiffController' => 'PhrictionController',
'PhrictionDocument' => 'PhrictionDAO',
'PhrictionDocumentController' => 'PhrictionController',
'PhrictionDocumentPreviewController' => 'PhrictionController',
'PhrictionDocumentStatus' => 'PhrictionConstants',
'PhrictionDocumentTestCase' => 'PhabricatorTestCase',
'PhrictionEditController' => 'PhrictionController',
'PhrictionHistoryController' => 'PhrictionController',
'PhrictionListController' => 'PhrictionController',
'QueryFormattingTestCase' => 'PhabricatorTestCase',
),
'requires_interface' =>
array(
'DefaultDatabaseConfigurationProvider' =>
array(
0 => 'DatabaseConfigurationProvider',
),
'DifferentialInlineComment' =>
array(
0 => 'PhabricatorInlineCommentInterface',
),
'PhabricatorAuditInlineComment' =>
array(
0 => 'PhabricatorInlineCommentInterface',
),
'PhabricatorPaste' =>
array(
0 => 'PhabricatorPolicyInterface',
),
'PhabricatorPolicyTestObject' =>
array(
0 => 'PhabricatorPolicyInterface',
),
),
));
diff --git a/src/applications/people/controller/list/PhabricatorPeopleListController.php b/src/applications/people/controller/list/PhabricatorPeopleListController.php
index 8a02146fec..cb41eab371 100644
--- a/src/applications/people/controller/list/PhabricatorPeopleListController.php
+++ b/src/applications/people/controller/list/PhabricatorPeopleListController.php
@@ -1,139 +1,140 @@
<?php
/*
* Copyright 2012 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
final class PhabricatorPeopleListController
extends PhabricatorPeopleController {
public function processRequest() {
$request = $this->getRequest();
$viewer = $request->getUser();
$is_admin = $viewer->getIsAdmin();
$user = new PhabricatorUser();
$count = queryfx_one(
$user->establishConnection('r'),
'SELECT COUNT(*) N FROM %T',
$user->getTableName());
$count = idx($count, 'N', 0);
$pager = new AphrontPagerView();
$pager->setOffset($request->getInt('page', 0));
$pager->setCount($count);
$pager->setURI($request->getRequestURI(), 'page');
$users = id(new PhabricatorPeopleQuery())
->needPrimaryEmail(true)
->executeWithPager($pager);
$rows = array();
foreach ($users as $user) {
- if ($user->getPrimaryEmail()->getIsVerified()) {
+ $primary_email = $user->loadPrimaryEmail();
+ if ($primary_email && $primary_email->getIsVerified()) {
$email = 'Verified';
} else {
$email = 'Unverified';
}
$status = array();
if ($user->getIsDisabled()) {
$status[] = 'Disabled';
}
if ($user->getIsAdmin()) {
$status[] = 'Admin';
}
if ($user->getIsSystemAgent()) {
$status[] = 'System Agent';
}
$status = implode(', ', $status);
$rows[] = array(
phabricator_date($user->getDateCreated(), $viewer),
phabricator_time($user->getDateCreated(), $viewer),
phutil_render_tag(
'a',
array(
'href' => '/p/'.$user->getUsername().'/',
),
phutil_escape_html($user->getUserName())),
phutil_escape_html($user->getRealName()),
$status,
$email,
phutil_render_tag(
'a',
array(
'class' => 'button grey small',
'href' => '/people/edit/'.$user->getID().'/',
),
'Administrate User'),
);
}
$table = new AphrontTableView($rows);
$table->setHeaders(
array(
'Join Date',
'Time',
'Username',
'Real Name',
'Roles',
'Email',
'',
));
$table->setColumnClasses(
array(
null,
'right',
'pri',
'wide',
null,
null,
'action',
));
$table->setColumnVisibility(
array(
true,
true,
true,
true,
$is_admin,
$is_admin,
$is_admin,
));
$panel = new AphrontPanelView();
$panel->setHeader('People ('.number_format($count).')');
$panel->appendChild($table);
$panel->appendChild($pager);
if ($is_admin) {
$panel->addButton(
phutil_render_tag(
'a',
array(
'href' => '/people/edit/',
'class' => 'button green',
),
'Create New Account'));
}
return $this->buildStandardPageResponse($panel, array(
'title' => 'People',
'tab' => 'directory',
));
}
}
diff --git a/src/applications/people/query/PhabricatorPeopleQuery.php b/src/applications/people/query/PhabricatorPeopleQuery.php
index ef53341622..727caaac1c 100644
--- a/src/applications/people/query/PhabricatorPeopleQuery.php
+++ b/src/applications/people/query/PhabricatorPeopleQuery.php
@@ -1,136 +1,124 @@
<?php
/*
* Copyright 2012 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
final class PhabricatorPeopleQuery extends PhabricatorOffsetPagedQuery {
private $usernames;
private $realnames;
private $emails;
private $phids;
private $ids;
private $needPrimaryEmail;
public function withIds(array $ids) {
$this->ids = $ids;
return $this;
}
public function withPhids(array $phids) {
$this->phids = $phids;
return $this;
}
public function withEmails(array $emails) {
$this->emails = $emails;
return $this;
}
public function withRealnames(array $realnames) {
$this->realnames = $realnames;
return $this;
}
public function withUsernames(array $usernames) {
$this->usernames = $usernames;
return $this;
}
public function needPrimaryEmail($need) {
$this->needPrimaryEmail = $need;
return $this;
}
public function execute() {
$table = new PhabricatorUser();
$conn_r = $table->establishConnection('r');
$joins_clause = $this->buildJoinsClause($conn_r);
$where_clause = $this->buildWhereClause($conn_r);
$limit_clause = $this->buildLimitClause($conn_r);
$data = queryfx_all(
$conn_r,
'SELECT * FROM %T user %Q %Q %Q',
$table->getTableName(),
$joins_clause,
$where_clause,
$limit_clause);
- $users = $table->loadAllFromArray($data);
-
- if ($users && $this->needPrimaryEmail) {
- $emails = id(new PhabricatorUserEmail())->loadAllWhere(
- 'userPHID IN (%Ls)',
- mpull($users, 'getPHID'));
- $emails = mpull($emails, null, 'getUserPHID');
- foreach ($users as $user) {
- // Fail gracefully if we have data integrity problems.
- if (empty($emails[$user->getPHID()])) {
- $user->attachPrimaryEmail(new PhabricatorUserEmail());
- } else {
- $user->attachPrimaryEmail($emails[$user->getPHID()]);
- }
- }
+ if ($this->needPrimaryEmail) {
+ $table->putInSet(new LiskDAOSet());
}
+ $users = $table->loadAllFromArray($data);
return $users;
}
private function buildJoinsClause($conn_r) {
$joins = array();
if ($this->emails) {
$email_table = new PhabricatorUserEmail();
$joins[] = qsprintf(
$conn_r,
'JOIN %T email ON email.userPHID = user.PHID',
$email_table->getTableName());
}
$joins = implode(' ', $joins);
return $joins;
}
private function buildWhereClause($conn_r) {
$where = array();
if ($this->usernames) {
$where[] = qsprintf($conn_r,
'user.userName IN (%Ls)',
$this->usernames);
}
if ($this->emails) {
$where[] = qsprintf($conn_r,
'email.address IN (%Ls)',
$this->emails);
}
if ($this->realnames) {
$where[] = qsprintf($conn_r,
'user.realName IN (%Ls)',
$this->realnames);
}
if ($this->phids) {
$where[] = qsprintf($conn_r,
'user.phid IN (%Ls)',
$this->phids);
}
if ($this->ids) {
$where[] = qsprintf($conn_r,
'user.id IN (%Ld)',
$this->ids);
}
return $this->formatWhereClause($where);
}
}
diff --git a/src/applications/people/query/__init__.php b/src/applications/people/query/__init__.php
index 457c5d565e..4bc9b325f4 100644
--- a/src/applications/people/query/__init__.php
+++ b/src/applications/people/query/__init__.php
@@ -1,18 +1,17 @@
<?php
/**
* This file is automatically generated. Lint this module to rebuild it.
* @generated
*/
phutil_require_module('phabricator', 'applications/people/storage/email');
phutil_require_module('phabricator', 'applications/people/storage/user');
phutil_require_module('phabricator', 'infrastructure/query/offsetpaged');
+phutil_require_module('phabricator', 'storage/lisk/dao');
phutil_require_module('phabricator', 'storage/qsprintf');
phutil_require_module('phabricator', 'storage/queryfx');
-phutil_require_module('phutil', 'utils');
-
phutil_require_source('PhabricatorPeopleQuery.php');
diff --git a/src/applications/people/storage/user/PhabricatorUser.php b/src/applications/people/storage/user/PhabricatorUser.php
index 639b984a33..a6055a66a8 100644
--- a/src/applications/people/storage/user/PhabricatorUser.php
+++ b/src/applications/people/storage/user/PhabricatorUser.php
@@ -1,600 +1,587 @@
<?php
/*
* Copyright 2012 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
final class PhabricatorUser extends PhabricatorUserDAO {
const SESSION_TABLE = 'phabricator_session';
const NAMETOKEN_TABLE = 'user_nametoken';
protected $phid;
protected $userName;
protected $realName;
protected $sex;
protected $passwordSalt;
protected $passwordHash;
protected $profileImagePHID;
protected $timezoneIdentifier = '';
protected $consoleEnabled = 0;
protected $consoleVisible = 0;
protected $consoleTab = '';
protected $conduitCertificate;
protected $isSystemAgent = 0;
protected $isAdmin = 0;
protected $isDisabled = 0;
private $preferences = null;
- private $primaryEmail;
protected function readField($field) {
switch ($field) {
case 'timezoneIdentifier':
// If the user hasn't set one, guess the server's time.
return nonempty(
$this->timezoneIdentifier,
date_default_timezone_get());
// Make sure these return booleans.
case 'isAdmin':
return (bool)$this->isAdmin;
case 'isDisabled':
return (bool)$this->isDisabled;
case 'isSystemAgent':
return (bool)$this->isSystemAgent;
default:
return parent::readField($field);
}
}
public function getConfiguration() {
return array(
self::CONFIG_AUX_PHID => true,
self::CONFIG_PARTIAL_OBJECTS => true,
) + parent::getConfiguration();
}
public function generatePHID() {
return PhabricatorPHID::generateNewPHID(
PhabricatorPHIDConstants::PHID_TYPE_USER);
}
public function setPassword($password) {
if (!$this->getPHID()) {
throw new Exception(
"You can not set a password for an unsaved user because their PHID ".
"is a salt component in the password hash.");
}
if (!strlen($password)) {
$this->setPasswordHash('');
} else {
$this->setPasswordSalt(md5(mt_rand()));
$hash = $this->hashPassword($password);
$this->setPasswordHash($hash);
}
return $this;
}
public function isLoggedIn() {
return !($this->getPHID() === null);
}
public function save() {
if (!$this->getConduitCertificate()) {
$this->setConduitCertificate($this->generateConduitCertificate());
}
$result = parent::save();
$this->updateNameTokens();
PhabricatorSearchUserIndexer::indexUser($this);
return $result;
}
private function generateConduitCertificate() {
return Filesystem::readRandomCharacters(255);
}
public function comparePassword($password) {
if (!strlen($password)) {
return false;
}
if (!strlen($this->getPasswordHash())) {
return false;
}
$password = $this->hashPassword($password);
return ($password === $this->getPasswordHash());
}
private function hashPassword($password) {
$password = $this->getUsername().
$password.
$this->getPHID().
$this->getPasswordSalt();
for ($ii = 0; $ii < 1000; $ii++) {
$password = md5($password);
}
return $password;
}
const CSRF_CYCLE_FREQUENCY = 3600;
const CSRF_TOKEN_LENGTH = 16;
const EMAIL_CYCLE_FREQUENCY = 86400;
const EMAIL_TOKEN_LENGTH = 24;
public function getCSRFToken($offset = 0) {
return $this->generateToken(
time() + (self::CSRF_CYCLE_FREQUENCY * $offset),
self::CSRF_CYCLE_FREQUENCY,
PhabricatorEnv::getEnvConfig('phabricator.csrf-key'),
self::CSRF_TOKEN_LENGTH);
}
public function validateCSRFToken($token) {
if (!$this->getPHID()) {
return true;
}
// When the user posts a form, we check that it contains a valid CSRF token.
// Tokens cycle each hour (every CSRF_CYLCE_FREQUENCY seconds) and we accept
// either the current token, the next token (users can submit a "future"
// token if you have two web frontends that have some clock skew) or any of
// the last 6 tokens. This means that pages are valid for up to 7 hours.
// There is also some Javascript which periodically refreshes the CSRF
// tokens on each page, so theoretically pages should be valid indefinitely.
// However, this code may fail to run (if the user loses their internet
// connection, or there's a JS problem, or they don't have JS enabled).
// Choosing the size of the window in which we accept old CSRF tokens is
// an issue of balancing concerns between security and usability. We could
// choose a very narrow (e.g., 1-hour) window to reduce vulnerability to
// attacks using captured CSRF tokens, but it's also more likely that real
// users will be affected by this, e.g. if they close their laptop for an
// hour, open it back up, and try to submit a form before the CSRF refresh
// can kick in. Since the user experience of submitting a form with expired
// CSRF is often quite bad (you basically lose data, or it's a big pain to
// recover at least) and I believe we gain little additional protection
// by keeping the window very short (the overwhelming value here is in
// preventing blind attacks, and most attacks which can capture CSRF tokens
// can also just capture authentication information [sniffing networks]
// or act as the user [xss]) the 7 hour default seems like a reasonable
// balance. Other major platforms have much longer CSRF token lifetimes,
// like Rails (session duration) and Django (forever), which suggests this
// is a reasonable analysis.
$csrf_window = 6;
for ($ii = -$csrf_window; $ii <= 1; $ii++) {
$valid = $this->getCSRFToken($ii);
if ($token == $valid) {
return true;
}
}
return false;
}
private function generateToken($epoch, $frequency, $key, $len) {
$time_block = floor($epoch / $frequency);
$vec = $this->getPHID().$this->getPasswordHash().$key.$time_block;
return substr(PhabricatorHash::digest($vec), 0, $len);
}
/**
* Issue a new session key to this user. Phabricator supports different
* types of sessions (like "web" and "conduit") and each session type may
* have multiple concurrent sessions (this allows a user to be logged in on
* multiple browsers at the same time, for instance).
*
* Note that this method is transport-agnostic and does not set cookies or
* issue other types of tokens, it ONLY generates a new session key.
*
* You can configure the maximum number of concurrent sessions for various
* session types in the Phabricator configuration.
*
* @param string Session type, like "web".
* @return string Newly generated session key.
*/
public function establishSession($session_type) {
$conn_w = $this->establishConnection('w');
if (strpos($session_type, '-') !== false) {
throw new Exception("Session type must not contain hyphen ('-')!");
}
// We allow multiple sessions of the same type, so when a caller requests
// a new session of type "web", we give them the first available session in
// "web-1", "web-2", ..., "web-N", up to some configurable limit. If none
// of these sessions is available, we overwrite the oldest session and
// reissue a new one in its place.
$session_limit = 1;
switch ($session_type) {
case 'web':
$session_limit = PhabricatorEnv::getEnvConfig('auth.sessions.web');
break;
case 'conduit':
$session_limit = PhabricatorEnv::getEnvConfig('auth.sessions.conduit');
break;
default:
throw new Exception("Unknown session type '{$session_type}'!");
}
$session_limit = (int)$session_limit;
if ($session_limit <= 0) {
throw new Exception(
"Session limit for '{$session_type}' must be at least 1!");
}
// NOTE: Session establishment is sensitive to race conditions, as when
// piping `arc` to `arc`:
//
// arc export ... | arc paste ...
//
// To avoid this, we overwrite an old session only if it hasn't been
// re-established since we read it.
// Consume entropy to generate a new session key, forestalling the eventual
// heat death of the universe.
$session_key = Filesystem::readRandomCharacters(40);
// Load all the currently active sessions.
$sessions = queryfx_all(
$conn_w,
'SELECT type, sessionKey, sessionStart FROM %T
WHERE userPHID = %s AND type LIKE %>',
PhabricatorUser::SESSION_TABLE,
$this->getPHID(),
$session_type.'-');
$sessions = ipull($sessions, null, 'type');
$sessions = isort($sessions, 'sessionStart');
$existing_sessions = array_keys($sessions);
// UNGUARDED WRITES: Logging-in users don't have CSRF stuff yet.
$unguarded = AphrontWriteGuard::beginScopedUnguardedWrites();
$retries = 0;
while (true) {
// Choose which 'type' we'll actually establish, i.e. what number we're
// going to append to the basic session type. To do this, just check all
// the numbers sequentially until we find an available session.
$establish_type = null;
for ($ii = 1; $ii <= $session_limit; $ii++) {
$try_type = $session_type.'-'.$ii;
if (!in_array($try_type, $existing_sessions)) {
$establish_type = $try_type;
$expect_key = $session_key;
$existing_sessions[] = $try_type;
// Ensure the row exists so we can issue an update below. We don't
// care if we race here or not.
queryfx(
$conn_w,
'INSERT IGNORE INTO %T (userPHID, type, sessionKey, sessionStart)
VALUES (%s, %s, %s, 0)',
self::SESSION_TABLE,
$this->getPHID(),
$establish_type,
$session_key);
break;
}
}
// If we didn't find an available session, choose the oldest session and
// overwrite it.
if (!$establish_type) {
$oldest = reset($sessions);
$establish_type = $oldest['type'];
$expect_key = $oldest['sessionKey'];
}
// This is so that we'll only overwrite the session if it hasn't been
// refreshed since we read it. If it has, the session key will be
// different and we know we're racing other processes. Whichever one
// won gets the session, we go back and try again.
queryfx(
$conn_w,
'UPDATE %T SET sessionKey = %s, sessionStart = UNIX_TIMESTAMP()
WHERE userPHID = %s AND type = %s AND sessionKey = %s',
self::SESSION_TABLE,
$session_key,
$this->getPHID(),
$establish_type,
$expect_key);
if ($conn_w->getAffectedRows()) {
// The update worked, so the session is valid.
break;
} else {
// We know this just got grabbed, so don't try it again.
unset($sessions[$establish_type]);
}
if (++$retries > $session_limit) {
throw new Exception("Failed to establish a session!");
}
}
$log = PhabricatorUserLog::newLog(
$this,
$this,
PhabricatorUserLog::ACTION_LOGIN);
$log->setDetails(
array(
'session_type' => $session_type,
'session_issued' => $establish_type,
));
$log->setSession($session_key);
$log->save();
return $session_key;
}
public function destroySession($session_key) {
$conn_w = $this->establishConnection('w');
queryfx(
$conn_w,
'DELETE FROM %T WHERE userPHID = %s AND sessionKey = %s',
self::SESSION_TABLE,
$this->getPHID(),
$session_key);
}
private function generateEmailToken(
PhabricatorUserEmail $email,
$offset = 0) {
$key = implode(
'-',
array(
PhabricatorEnv::getEnvConfig('phabricator.csrf-key'),
$this->getPHID(),
$email->getVerificationCode(),
));
return $this->generateToken(
time() + ($offset * self::EMAIL_CYCLE_FREQUENCY),
self::EMAIL_CYCLE_FREQUENCY,
$key,
self::EMAIL_TOKEN_LENGTH);
}
public function validateEmailToken(
PhabricatorUserEmail $email,
$token) {
for ($ii = -1; $ii <= 1; $ii++) {
$valid = $this->generateEmailToken($email, $ii);
if ($token == $valid) {
return true;
}
}
return false;
}
public function getEmailLoginURI(PhabricatorUserEmail $email = null) {
if (!$email) {
$email = $this->loadPrimaryEmail();
if (!$email) {
throw new Exception("User has no primary email!");
}
}
$token = $this->generateEmailToken($email);
$uri = PhabricatorEnv::getProductionURI('/login/etoken/'.$token.'/');
$uri = new PhutilURI($uri);
return $uri->alter('email', $email->getAddress());
}
public function loadPrimaryEmailAddress() {
$email = $this->loadPrimaryEmail();
if (!$email) {
throw new Exception("User has no primary email address!");
}
return $email->getAddress();
}
public function loadPrimaryEmail() {
- return id(new PhabricatorUserEmail())->loadOneWhere(
- 'userPHID = %s AND isPrimary = %d',
- $this->getPHID(),
- 1);
- }
-
- public function attachPrimaryEmail(PhabricatorUserEmail $email) {
- $this->primaryEmail = $email;
- return $this;
- }
-
- public function getPrimaryEmail() {
- if ($this->primaryEmail === null) {
- throw new Exception(
- "Call attachPrimaryEmail() before getPrimaryEmail()!");
- }
- return $this->primaryEmail;
+ return $this->loadOneRelative(
+ new PhabricatorUserEmail(),
+ 'userPHID',
+ 'getPHID',
+ '(isPrimary = 1)');
}
public function loadPreferences() {
if ($this->preferences) {
return $this->preferences;
}
$preferences = id(new PhabricatorUserPreferences())->loadOneWhere(
'userPHID = %s',
$this->getPHID());
if (!$preferences) {
$preferences = new PhabricatorUserPreferences();
$preferences->setUserPHID($this->getPHID());
$default_dict = array(
PhabricatorUserPreferences::PREFERENCE_TITLES => 'glyph',
PhabricatorUserPreferences::PREFERENCE_EDITOR => '',
PhabricatorUserPreferences::PREFERENCE_MONOSPACED => '');
$preferences->setPreferences($default_dict);
}
$this->preferences = $preferences;
return $preferences;
}
public function loadEditorLink($path, $line, $callsign) {
$editor = $this->loadPreferences()->getPreference(
PhabricatorUserPreferences::PREFERENCE_EDITOR);
if ($editor) {
return strtr($editor, array(
'%%' => '%',
'%f' => phutil_escape_uri($path),
'%l' => phutil_escape_uri($line),
'%r' => phutil_escape_uri($callsign),
));
}
}
private static function tokenizeName($name) {
if (function_exists('mb_strtolower')) {
$name = mb_strtolower($name, 'UTF-8');
} else {
$name = strtolower($name);
}
$name = trim($name);
if (!strlen($name)) {
return array();
}
return preg_split('/\s+/', $name);
}
/**
* Populate the nametoken table, which used to fetch typeahead results. When
* a user types "linc", we want to match "Abraham Lincoln" from on-demand
* typeahead sources. To do this, we need a separate table of name fragments.
*/
public function updateNameTokens() {
$tokens = array_merge(
self::tokenizeName($this->getRealName()),
self::tokenizeName($this->getUserName()));
$tokens = array_unique($tokens);
$table = self::NAMETOKEN_TABLE;
$conn_w = $this->establishConnection('w');
$sql = array();
foreach ($tokens as $token) {
$sql[] = qsprintf(
$conn_w,
'(%d, %s)',
$this->getID(),
$token);
}
queryfx(
$conn_w,
'DELETE FROM %T WHERE userID = %d',
$table,
$this->getID());
if ($sql) {
queryfx(
$conn_w,
'INSERT INTO %T (userID, token) VALUES %Q',
$table,
implode(', ', $sql));
}
}
public function sendWelcomeEmail(PhabricatorUser $admin) {
$admin_username = $admin->getUserName();
$admin_realname = $admin->getRealName();
$user_username = $this->getUserName();
$is_serious = PhabricatorEnv::getEnvConfig('phabricator.serious-business');
$base_uri = PhabricatorEnv::getProductionURI('/');
$uri = $this->getEmailLoginURI();
$body = <<<EOBODY
Welcome to Phabricator!
{$admin_username} ({$admin_realname}) has created an account for you.
Username: {$user_username}
To login to Phabricator, follow this link and set a password:
{$uri}
After you have set a password, you can login in the future by going here:
{$base_uri}
EOBODY;
if (!$is_serious) {
$body .= <<<EOBODY
Love,
Phabricator
EOBODY;
}
$mail = id(new PhabricatorMetaMTAMail())
->addTos(array($this->getPHID()))
->setSubject('[Phabricator] Welcome to Phabricator')
->setBody($body)
->setFrom($admin->getPHID())
->saveAndSend();
}
public static function validateUsername($username) {
return (bool)preg_match('/^[a-zA-Z0-9]+$/', $username);
}
public static function getDefaultProfileImageURI() {
return celerity_get_resource_uri('/rsrc/image/avatar.png');
}
public function loadProfileImageURI() {
$src_phid = $this->getProfileImagePHID();
$file = id(new PhabricatorFile())->loadOneWhere('phid = %s', $src_phid);
if ($file) {
return $file->getBestURI();
}
return self::getDefaultProfileImageURI();
}
public function getFullName() {
return $this->getUsername().' ('.$this->getRealName().')';
}
public static function loadOneWithEmailAddress($address) {
$email = id(new PhabricatorUserEmail())->loadOneWhere(
'address = %s',
$address);
if (!$email) {
return null;
}
return id(new PhabricatorUser())->loadOneWhere(
'phid = %s',
$email->getUserPHID());
}
}
diff --git a/src/storage/lisk/dao/LiskDAO.php b/src/storage/lisk/dao/LiskDAO.php
index 504bd8dec6..4e6eb0ef36 100644
--- a/src/storage/lisk/dao/LiskDAO.php
+++ b/src/storage/lisk/dao/LiskDAO.php
@@ -1,1738 +1,1775 @@
<?php
/*
* Copyright 2012 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* Simple object-authoritative data access object that makes it easy to build
* stuff that you need to save to a database. Basically, it means that the
* amount of boilerplate code (and, particularly, boilerplate SQL) you need
* to write is greatly reduced.
*
* Lisk makes it fairly easy to build something quickly and end up with
* reasonably high-quality code when you're done (e.g., getters and setters,
* objects, transactions, reasonably structured OO code). It's also very thin:
* you can break past it and use MySQL and other lower-level tools when you
* need to in those couple of cases where it doesn't handle your workflow
* gracefully.
*
* However, Lisk won't scale past one database and lacks many of the features
* of modern DAOs like Hibernate: for instance, it does not support joins or
* polymorphic storage.
*
* This means that Lisk is well-suited for tools like Differential, but often a
* poor choice elsewhere. And it is strictly unsuitable for many projects.
*
* Lisk's model is object-authoritative: the PHP class definition is the
* master authority for what the object looks like.
*
* =Building New Objects=
*
* To create new Lisk objects, extend @{class:LiskDAO} and implement
* @{method:establishLiveConnection}. It should return an
* @{class:AphrontDatabaseConnection}; this will tell Lisk where to save your
* objects.
*
* class Dog extends LiskDAO {
*
* protected $name;
* protected $breed;
*
* public function establishLiveConnection() {
* return $some_connection_object;
* }
* }
*
* Now, you should create your table:
*
* lang=sql
* CREATE TABLE dog (
* id int unsigned not null auto_increment primary key,
* name varchar(32) not null,
* breed varchar(32) not null,
* dateCreated int unsigned not null,
* dateModified int unsigned not null
* );
*
* For each property in your class, add a column with the same name to the table
* (see @{method:getConfiguration} for information about changing this mapping).
* Additionally, you should create the three columns `id`, `dateCreated` and
* `dateModified`. Lisk will automatically manage these, using them to implement
* autoincrement IDs and timestamps. If you do not want to use these features,
* see @{method:getConfiguration} for information on disabling them. At a bare
* minimum, you must normally have an `id` column which is a primary or unique
* key with a numeric type, although you can change its name by overriding
* @{method:getIDKey} or disable it entirely by overriding @{method:getIDKey} to
* return null. Note that many methods rely on a single-part primary key and
* will no longer work (they will throw) if you disable it.
*
* As you add more properties to your class in the future, remember to add them
* to the database table as well.
*
* Lisk will now automatically handle these operations: getting and setting
* properties, saving objects, loading individual objects, loading groups
* of objects, updating objects, managing IDs, updating timestamps whenever
* an object is created or modified, and some additional specialized
* operations.
*
* = Creating, Retrieving, Updating, and Deleting =
*
* To create and persist a Lisk object, use @{method:save}:
*
* $dog = id(new Dog())
* ->setName('Sawyer')
* ->setBreed('Pug')
* ->save();
*
* Note that **Lisk automatically builds getters and setters for all of your
* object's protected properties** via @{method:__call}. If you want to add
* custom behavior to your getters or setters, you can do so by overriding the
* @{method:readField} and @{method:writeField} methods.
*
* Calling @{method:save} will persist the object to the database. After calling
* @{method:save}, you can call @{method:getID} to retrieve the object's ID.
*
* To load objects by ID, use the @{method:load} method:
*
* $dog = id(new Dog())->load($id);
*
* This will load the Dog record with ID $id into $dog, or ##null## if no such
* record exists (@{method:load} is an instance method rather than a static
* method because PHP does not support late static binding, at least until PHP
* 5.3).
*
* To update an object, change its properties and save it:
*
* $dog->setBreed('Lab')->save();
*
* To delete an object, call @{method:delete}:
*
* $dog->delete();
*
* That's Lisk CRUD in a nutshell.
*
* = Queries =
*
* Often, you want to load a bunch of objects, or execute a more specialized
* query. Use @{method:loadAllWhere} or @{method:loadOneWhere} to do this:
*
* $pugs = $dog->loadAllWhere('breed = %s', 'Pug');
* $sawyer = $dog->loadOneWhere('name = %s', 'Sawyer');
*
* These methods work like @{function:queryfx}, but only take half of a query
* (the part after the WHERE keyword). Lisk will handle the connection, columns,
* and object construction; you are responsible for the rest of it.
* @{method:loadAllWhere} returns a list of objects, while
* @{method:loadOneWhere} returns a single object (or `null`).
*
* There's also a @{method:loadRelatives} method which helps to prevent the 1+N
* queries problem.
*
* = Managing Transactions =
*
* Lisk uses a transaction stack, so code does not generally need to be aware
* of the transactional state of objects to implement correct transaction
* semantics:
*
* $obj->openTransaction();
* $obj->save();
* $other->save();
* // ...
* $other->openTransaction();
* $other->save();
* $another->save();
* if ($some_condition) {
* $other->saveTransaction();
* } else {
* $other->killTransaction();
* }
* // ...
* $obj->saveTransaction();
*
* Assuming ##$obj##, ##$other## and ##$another## live on the same database,
* this code will work correctly by establishing savepoints.
*
* Selects whose data are used later in the transaction should be included in
* @{method:beginReadLocking} or @{method:beginWriteLocking} block.
*
* @task conn Managing Connections
* @task config Configuring Lisk
* @task load Loading Objects
* @task info Examining Objects
* @task save Writing Objects
* @task hook Hooks and Callbacks
* @task util Utilities
* @task xaction Managing Transactions
* @task isolate Isolation for Unit Testing
*
* @group storage
*/
abstract class LiskDAO {
const CONFIG_OPTIMISTIC_LOCKS = 'enable-locks';
const CONFIG_IDS = 'id-mechanism';
const CONFIG_TIMESTAMPS = 'timestamps';
const CONFIG_AUX_PHID = 'auxiliary-phid';
const CONFIG_SERIALIZATION = 'col-serialization';
const CONFIG_PARTIAL_OBJECTS = 'partial-objects';
const SERIALIZATION_NONE = 'id';
const SERIALIZATION_JSON = 'json';
const SERIALIZATION_PHP = 'php';
const IDS_AUTOINCREMENT = 'ids-auto';
const IDS_PHID = 'ids-phid';
const IDS_MANUAL = 'ids-manual';
private $__dirtyFields = array();
private $__missingFields = array();
private static $processIsolationLevel = 0;
private static $transactionIsolationLevel = 0;
private static $__checkedClasses = array();
private $__ephemeral = false;
private static $connections = array();
private $inSet = null;
/**
* Build an empty object.
*
* @return obj Empty object.
*/
public function __construct() {
$id_key = $this->getIDKey();
if ($id_key) {
$this->$id_key = null;
}
if ($this->getConfigOption(self::CONFIG_PARTIAL_OBJECTS)) {
$this->resetDirtyFields();
$this_class = get_class($this);
if (empty(self::$__checkedClasses[$this_class])) {
self::$__checkedClasses = true;
if (PhabricatorEnv::getEnvConfig('lisk.check_property_methods')) {
$class = new ReflectionClass(get_class($this));
$methods = $class->getMethods();
$properties = $this->getProperties();
foreach ($methods as $method) {
$name = strtolower($method->getName());
if (!(strncmp($name, 'get', 3) && strncmp($name, 'set', 3))) {
$name = substr($name, 3);
$declaring_class_name = $method->getDeclaringClass()->getName();
if (isset($properties[$name]) &&
$declaring_class_name !== 'LiskDAO') {
throw new Exception(
"Cannot implement method {$method->getName()} in ".
"{$declaring_class_name}.");
}
}
}
}
}
}
}
/* -( Managing Connections )----------------------------------------------- */
/**
* Establish a live connection to a database service. This method should
* return a new connection. Lisk handles connection caching and management;
* do not perform caching deeper in the stack.
*
* @param string Mode, either 'r' (reading) or 'w' (reading and writing).
* @return AphrontDatabaseConnection New database connection.
* @task conn
*/
abstract protected function establishLiveConnection($mode);
/**
* Return a namespace for this object's connections in the connection cache.
* Generally, the database name is appropriate. Two connections are considered
* equivalent if they have the same connection namespace and mode.
*
* @return string Connection namespace for cache
* @task conn
*/
abstract protected function getConnectionNamespace();
/**
* Get an existing, cached connection for this object.
*
* @param mode Connection mode.
* @return AprontDatabaseConnection|null Connection, if it exists in cache.
* @task conn
*/
protected function getEstablishedConnection($mode) {
$key = $this->getConnectionNamespace().':'.$mode;
if (isset(self::$connections[$key])) {
return self::$connections[$key];
}
return null;
}
/**
* Store a connection in the connection cache.
*
* @param mode Connection mode.
* @param AphrontDatabaseConnection Connection to cache.
* @return this
* @task conn
*/
protected function setEstablishedConnection(
$mode,
AphrontDatabaseConnection $connection) {
$key = $this->getConnectionNamespace().':'.$mode;
self::$connections[$key] = $connection;
return $this;
}
/* -( Configuring Lisk )--------------------------------------------------- */
/**
* Change Lisk behaviors, like optimistic locks and timestamps. If you want
* to change these behaviors, you should override this method in your child
* class and change the options you're interested in. For example:
*
* public function getConfiguration() {
* return array(
* Lisk_DataAccessObject::CONFIG_EXAMPLE => true,
* ) + parent::getConfiguration();
* }
*
* The available options are:
*
* CONFIG_OPTIMISTIC_LOCKS
* Lisk automatically performs optimistic locking on objects, which protects
* you from read-modify-write concurrency problems. Lock failures are
* detected at write time and arise when two users read an object, then both
* save it. In theory, you should detect these failures and accommodate them
* in some sensible way (for instance, by showing the user differences
* between the original record and the copy they are trying to update, and
* prompting them to merge them). In practice, most Lisk tools are quick
* and dirty and don't get to that level of sophistication, but optimistic
* locks can still protect you from yourself sometimes. If you don't want
* to use optimistic locks, you can disable them. The performance cost of
* doing this locking is very very small (optimistic locks were chosen
* because they're simple and cheap, and highly optimized for the case where
* collisions are rare). By default, this option is OFF.
*
* CONFIG_IDS
* Lisk objects need to have a unique identifying ID. The three mechanisms
* available for generating this ID are IDS_AUTOINCREMENT (default, assumes
* the ID column is an autoincrement primary key), IDS_PHID (to generate a
* unique PHID for each object) or IDS_MANUAL (you are taking full
* responsibility for ID management).
*
* CONFIG_TIMESTAMPS
* Lisk can automatically handle keeping track of a `dateCreated' and
* `dateModified' column, which it will update when it creates or modifies
* an object. If you don't want to do this, you may disable this option.
* By default, this option is ON.
*
* CONFIG_AUX_PHID
* This option can be enabled by being set to some truthy value. The meaning
* of this value is defined by your PHID generation mechanism. If this option
* is enabled, a `phid' property will be populated with a unique PHID when an
* object is created (or if it is saved and does not currently have one). You
* need to override generatePHID() and hook it into your PHID generation
* mechanism for this to work. By default, this option is OFF.
*
* CONFIG_SERIALIZATION
* You can optionally provide a column serialization map that will be applied
* to values when they are written to the database. For example:
*
* self::CONFIG_SERIALIZATION => array(
* 'complex' => self::SERIALIZATION_JSON,
* )
*
* This will cause Lisk to JSON-serialize the 'complex' field before it is
* written, and unserialize it when it is read.
*
* CONFIG_PARTIAL_OBJECTS
* Sometimes, it is useful to load only some fields of an object (such as
* when you are loading all objects of a class, but only care about a few
* fields). Turning on this option (by setting it to a truthy value) allows
* users of the class to create/use partial objects, but it comes with some
* side effects: your class cannot override the setters and getters provided
* by Lisk (use readField and writeField instead), and you should not
* directly access or assign protected members of your class (use the getters
* and setters).
*
*
* @return dictionary Map of configuration options to values.
*
* @task config
*/
protected function getConfiguration() {
return array(
self::CONFIG_OPTIMISTIC_LOCKS => false,
self::CONFIG_IDS => self::IDS_AUTOINCREMENT,
self::CONFIG_TIMESTAMPS => true,
self::CONFIG_PARTIAL_OBJECTS => false,
);
}
/**
* Determine the setting of a configuration option for this class of objects.
*
* @param const Option name, one of the CONFIG_* constants.
* @return mixed Option value, if configured (null if unavailable).
*
* @task config
*/
public function getConfigOption($option_name) {
static $options = null;
if (!isset($options)) {
$options = $this->getConfiguration();
}
return idx($options, $option_name);
}
/* -( Loading Objects )---------------------------------------------------- */
/**
* Load an object by ID. You need to invoke this as an instance method, not
* a class method, because PHP doesn't have late static binding (until
* PHP 5.3.0). For example:
*
* $dog = id(new Dog())->load($dog_id);
*
* @param int Numeric ID identifying the object to load.
* @return obj|null Identified object, or null if it does not exist.
*
* @task load
*/
public function load($id) {
if (!($id = (int)$id)) {
throw new Exception("Bogus ID provided to load().");
}
return $this->loadOneWhere(
'%C = %d',
$this->getIDKeyForUse(),
$id);
}
/**
* Loads all of the objects, unconditionally.
*
* @return dict Dictionary of all persisted objects of this type, keyed
* on object ID.
*
* @task load
*/
public function loadAll() {
return $this->loadAllWhere('1 = 1');
}
/**
* Loads all objects, but only fetches the specified columns.
*
* @param array Array of canonical column names as strings
* @return dict Dictionary of all objects, keyed by ID.
*
* @task load
*/
public function loadColumns(array $columns) {
return $this->loadColumnsWhere($columns, '1 = 1');
}
/**
* Load all objects which match a WHERE clause. You provide everything after
* the 'WHERE'; Lisk handles everything up to it. For example:
*
* $old_dogs = id(new Dog())->loadAllWhere('age > %d', 7);
*
* The pattern and arguments are as per queryfx().
*
* @param string queryfx()-style SQL WHERE clause.
* @param ... Zero or more conversions.
* @return dict Dictionary of matching objects, keyed on ID.
*
* @task load
*/
public function loadAllWhere($pattern/*, $arg, $arg, $arg ... */) {
$args = func_get_args();
array_unshift($args, null);
$data = call_user_func_array(
array($this, 'loadRawDataWhere'),
$args);
return $this->loadAllFromArray($data);
}
/**
* Loads selected columns from objects that match a WHERE clause. You must
* provide everything after the WHERE. See loadAllWhere().
*
* @param array List of column names.
* @param string queryfx()-style SQL WHERE clause.
* @param ... Zero or more conversions.
* @return dict Dictionary of matching objecks, keyed by ID.
*
* @task load
*/
public function loadColumnsWhere(array $columns, $pattern/*, $args... */) {
if (!$this->getConfigOption(self::CONFIG_PARTIAL_OBJECTS)) {
throw new BadMethodCallException(
"This class does not support partial objects.");
}
$args = func_get_args();
$data = call_user_func_array(
array($this, 'loadRawDataWhere'),
$args);
return $this->loadAllFromArray($data);
}
/**
* Load a single object identified by a 'WHERE' clause. You provide
* everything after the 'WHERE', and Lisk builds the first half of the
* query. See loadAllWhere(). This method is similar, but returns a single
* result instead of a list.
*
* @param string queryfx()-style SQL WHERE clause.
* @param ... Zero or more conversions.
* @return obj|null Matching object, or null if no object matches.
*
* @task load
*/
public function loadOneWhere($pattern/*, $arg, $arg, $arg ... */) {
$args = func_get_args();
array_unshift($args, null);
$data = call_user_func_array(
array($this, 'loadRawDataWhere'),
$args);
if (count($data) > 1) {
throw new AphrontQueryCountException(
"More than 1 result from loadOneWhere()!");
}
$data = reset($data);
if (!$data) {
return null;
}
return $this->loadFromArray($data);
}
protected function loadRawDataWhere($columns, $pattern/*, $args... */) {
$connection = $this->establishConnection('r');
$lock_clause = '';
if ($connection->isReadLocking()) {
$lock_clause = 'FOR UPDATE';
} else if ($connection->isWriteLocking()) {
$lock_clause = 'LOCK IN SHARE MODE';
}
$args = func_get_args();
$args = array_slice($args, 2);
if (!$columns) {
$column = '*';
} else {
$column = '%LC';
$columns[] = $this->getIDKey();
$properties = $this->getProperties();
$this->__missingFields = array_diff_key(
array_flip($properties),
array_flip($columns));
}
$pattern = 'SELECT '.$column.' FROM %T WHERE '.$pattern.' %Q';
array_unshift($args, $this->getTableName());
if ($columns) {
array_unshift($args, $columns);
}
array_push($args, $lock_clause);
array_unshift($args, $pattern);
return call_user_func_array(
array($connection, 'queryData'),
$args);
}
/**
* Reload an object from the database, discarding any changes to persistent
* properties. If the object uses optimistic locks and you are in a locking
* mode while transactional, this will effectively synchronize the locks.
* This is pretty heady. It is unlikely you need to use this method.
*
* @return this
*
* @task load
*/
public function reload() {
if (!$this->getID()) {
throw new Exception("Unable to reload object that hasn't been loaded!");
}
$use_locks = $this->getConfigOption(self::CONFIG_OPTIMISTIC_LOCKS);
if (!$use_locks) {
$result = $this->loadOneWhere(
'%C = %d',
$this->getIDKeyForUse(),
$this->getID());
} else {
$result = $this->loadOneWhere(
'%C = %d AND %C = %d',
$this->getIDKeyForUse(),
$this->getID(),
'version',
$this->getVersion());
}
if (!$result) {
throw new AphrontQueryObjectMissingException($use_locks);
}
return $this;
}
/**
* Initialize this object's properties from a dictionary. Generally, you
* load single objects with loadOneWhere(), but sometimes it may be more
* convenient to pull data from elsewhere directly (e.g., a complicated
* join via queryData()) and then load from an array representation.
*
* @param dict Dictionary of properties, which should be equivalent to
* selecting a row from the table or calling getProperties().
* @return this
*
* @task load
*/
public function loadFromArray(array $row) {
// TODO: We should load only valid properties.
$map = array();
foreach ($row as $k => $v) {
$map[$k] = $v;
}
$this->willReadData($map);
foreach ($map as $prop => $value) {
$this->$prop = $value;
}
$this->didReadData();
return $this;
}
/**
* Initialize a list of objects from a list of dictionaries. Usually you
* load lists of objects with loadAllWhere(), but sometimes that isn't
* flexible enough. One case is if you need to do joins to select the right
* objects:
*
* function loadAllWithOwner($owner) {
* $data = $this->queryData(
* 'SELECT d.*
* FROM owner o
* JOIN owner_has_dog od ON o.id = od.ownerID
* JOIN dog d ON od.dogID = d.id
* WHERE o.id = %d',
* $owner);
* return $this->loadAllFromArray($data);
* }
*
* This is a lot messier than loadAllWhere(), but more flexible.
*
* @param list List of property dictionaries.
* @return dict List of constructed objects, keyed on ID.
*
* @task load
*/
public function loadAllFromArray(array $rows) {
$result = array();
$id_key = $this->getIDKey();
foreach ($rows as $row) {
$obj = clone $this;
if ($id_key && isset($row[$id_key])) {
$result[$row[$id_key]] = $obj->loadFromArray($row);
} else {
$result[] = $obj->loadFromArray($row);
}
if ($this->inSet) {
$this->inSet->addToSet($obj);
}
}
return $result;
}
/**
* This method helps to prevent the 1+N queries problem. It happens when you
* execute a query for each row in a result set. Like in this code:
*
* COUNTEREXAMPLE, name=Easy to write but expensive to execute
* $diffs = id(new DifferentialDiff())->loadAllWhere(
* 'revisionID = %d',
* $revision->getID());
* foreach ($diffs as $diff) {
* $changesets = id(new DifferentialChangeset())->loadAllWhere(
* 'diffID = %d',
* $diff->getID());
* // Do something with $changesets.
* }
*
* One can solve this problem by reading all the dependent objects at once and
* assigning them later:
*
* COUNTEREXAMPLE, name=Cheaper to execute but harder to write and maintain
* $diffs = id(new DifferentialDiff())->loadAllWhere(
* 'revisionID = %d',
* $revision->getID());
* $all_changesets = id(new DifferentialChangeset())->loadAllWhere(
* 'diffID IN (%Ld)',
* mpull($diffs, 'getID'));
* $all_changesets = mgroup($all_changesets, 'getDiffID');
* foreach ($diffs as $diff) {
* $changesets = idx($all_changesets, $diff->getID(), array());
* // Do something with $changesets.
* }
*
* The method @{method:loadRelatives} abstracts this approach which allows
* writing a code which is simple and efficient at the same time:
*
* name=Easy to write and cheap to execute
* $diffs = $revision->loadRelatives(new DifferentialDiff(), 'revisionID');
* foreach ($diffs as $diff) {
* $changesets = $diff->loadRelatives(
* new DifferentialChangeset(),
* 'diffID');
* // Do something with $changesets.
* }
*
* This will load dependent objects for all diffs in the first call of
* @{method:loadRelatives} and use this result for all following calls.
*
* The method supports working with set of sets, like in this code:
*
* $diffs = $revision->loadRelatives(new DifferentialDiff(), 'revisionID');
* foreach ($diffs as $diff) {
* $changesets = $diff->loadRelatives(
* new DifferentialChangeset(),
* 'diffID');
* foreach ($changesets as $changeset) {
* $hunks = $changeset->loadRelatives(
* new DifferentialHunk(),
* 'changesetID');
* // Do something with hunks.
* }
* }
*
* This code will execute just three queries - one to load all diffs, one to
* load all their related changesets and one to load all their related hunks.
* You can try to write an equivalent code without using this method as
* a homework.
*
* The method also supports retrieving referenced objects, for example authors
- * of all diffs:
+ * of all diffs (using shortcut @{method:loadOneRelative}):
*
* foreach ($diffs as $diff) {
- * $author = head($diff->loadRelatives(
+ * $author = $diff->loadOneRelative(
* new PhabricatorUser(),
* 'phid',
- * 'getAuthorPHID'));
+ * 'getAuthorPHID');
* // Do something with author.
* }
*
* It is also possible to specify additional conditions for the `WHERE`
* clause. Similarly to @{method:loadAllWhere}, you can specify everything
* after `WHERE` (except `LIMIT`). Contrary to @{method:loadAllWhere}, it is
* allowed to pass only a constant string (`%` doesn't have a special
* meaning). This is intentional to avoid mistakes with using data from one
* row in retrieving other rows. Example of a correct usage:
*
- * $status = head($author->loadRelatives(
+ * $status = $author->loadOneRelative(
* new PhabricatorUserStatus(),
* 'userPHID',
* 'getPHID',
- * '(UNIX_TIMESTAMP() BETWEEN dateFrom AND dateTo)'));
+ * '(UNIX_TIMESTAMP() BETWEEN dateFrom AND dateTo)');
*
* @param LiskDAO Type of objects to load.
* @param string Name of the column in target table.
* @param string Method name in this table.
* @param string Additional constraints on returned rows. It supports no
* placeholders and requires putting the WHERE part into
* parentheses. It's not possible to use LIMIT.
* @return list Objects of type $object.
*
* @task load
*/
public function loadRelatives(
LiskDAO $object,
$foreign_column,
$key_method = 'getID',
$where = '') {
if (!$this->inSet) {
id(new LiskDAOSet())->addToSet($this);
}
$relatives = $this->inSet->loadRelatives(
$object,
$foreign_column,
$key_method,
$where);
return idx($relatives, $this->$key_method(), array());
}
+ /**
+ * Load referenced row. See @{method:loadRelatives} for details.
+ *
+ * @param LiskDAO Type of objects to load.
+ * @param string Name of the column in target table.
+ * @param string Method name in this table.
+ * @param string Additional constraints on returned rows. It supports no
+ * placeholders and requires putting the WHERE part into
+ * parentheses. It's not possible to use LIMIT.
+ * @return LiskDAO Object of type $object or null if there's no such object.
+ *
+ * @task load
+ */
+ final public function loadOneRelative(
+ LiskDAO $object,
+ $foreign_column,
+ $key_method = 'getID',
+ $where = '') {
+
+ $relatives = $this->loadRelatives(
+ $object,
+ $foreign_column,
+ $key_method,
+ $where);
+
+ if (!$relatives) {
+ return null;
+ }
+
+ if (count($relatives) > 1) {
+ throw new AphrontQueryCountException(
+ "More than 1 result from loadOneRelative()!");
+ }
+
+ return reset($relatives);
+ }
+
final public function putInSet(LiskDAOSet $set) {
$this->inSet = $set;
return $this;
}
/* -( Examining Objects )-------------------------------------------------- */
/**
* Retrieve the unique, numerical ID identifying this object. This value
* will be null if the object hasn't been persisted.
*
* @return int Unique numerical ID.
*
* @task info
*/
public function getID() {
static $id_key = null;
if ($id_key === null) {
$id_key = $this->getIDKeyForUse();
}
return $this->$id_key;
}
/**
* Retrieve a list of all object properties. This list only includes
* properties that are declared as protected, and it is expected that
* all properties returned by this function should be persisted to the
* database.
* Properties that should not be persisted must be declared as private.
*
* @return dict Dictionary of normalized (lowercase) to canonical (original
* case) property names.
*
* @task info
*/
protected function getProperties() {
static $properties = null;
if (!isset($properties)) {
$class = new ReflectionClass(get_class($this));
$properties = array();
foreach ($class->getProperties(ReflectionProperty::IS_PROTECTED) as $p) {
$properties[strtolower($p->getName())] = $p->getName();
}
$id_key = $this->getIDKey();
if ($id_key) {
if (!isset($properties[strtolower($id_key)])) {
$properties[strtolower($id_key)] = $id_key;
}
}
if ($this->getConfigOption(self::CONFIG_OPTIMISTIC_LOCKS)) {
$properties['version'] = 'version';
}
if ($this->getConfigOption(self::CONFIG_TIMESTAMPS)) {
$properties['datecreated'] = 'dateCreated';
$properties['datemodified'] = 'dateModified';
}
if (!$this->isPHIDPrimaryID() &&
$this->getConfigOption(self::CONFIG_AUX_PHID)) {
$properties['phid'] = 'phid';
}
}
return $properties;
}
/**
* Check if a property exists on this object.
*
* @return string|null Canonical property name, or null if the property
* does not exist.
*
* @task info
*/
protected function checkProperty($property) {
static $properties = null;
if ($properties === null) {
$properties = $this->getProperties();
}
$property = strtolower($property);
if (empty($properties[$property])) {
return null;
}
return $properties[$property];
}
/**
* Get or build the database connection for this object.
*
* @return LiskDatabaseConnection Lisk connection object.
*
* @task info
*/
public function establishConnection($mode) {
if ($mode != 'r' && $mode != 'w') {
throw new Exception("Unknown mode '{$mode}', should be 'r' or 'w'.");
}
if (self::shouldIsolateAllLiskEffectsToCurrentProcess()) {
$mode = 'isolate-'.$mode;
$connection = $this->getEstablishedConnection($mode);
if (!$connection) {
$connection = $this->establishIsolatedConnection($mode);
$this->setEstablishedConnection($mode, $connection);
}
return $connection;
}
if (self::shouldIsolateAllLiskEffectsToTransactions()) {
// If we're doing fixture transaction isolation, force the mode to 'w'
// so we always get the same connection for reads and writes, and thus
// can see the writes inside the transaction.
$mode = 'w';
}
// TODO: There is currently no protection on 'r' queries against writing.
$connection = null;
if ($mode == 'r') {
// If we're requesting a read connection but already have a write
// connection, reuse the write connection so that reads can take place
// inside transactions.
$connection = $this->getEstablishedConnection('w');
}
if (!$connection) {
$connection = $this->getEstablishedConnection($mode);
}
if (!$connection) {
$connection = $this->establishLiveConnection($mode);
if (self::shouldIsolateAllLiskEffectsToTransactions()) {
$connection->openTransaction();
}
$this->setEstablishedConnection($mode, $connection);
}
return $connection;
}
/**
* Convert this object into a property dictionary. This dictionary can be
* restored into an object by using loadFromArray() (unless you're using
* legacy features with CONFIG_CONVERT_CAMELCASE, but in that case you should
* just go ahead and die in a fire).
*
* @return dict Dictionary of object properties.
*
* @task info
*/
protected function getPropertyValues() {
$map = array();
foreach ($this->getProperties() as $p) {
// We may receive a warning here for properties we've implicitly added
// through configuration; squelch it.
$map[$p] = @$this->$p;
}
return $map;
}
/* -( Writing Objects )---------------------------------------------------- */
/**
* Make an object read-only.
*
* Making an object ephemeral indicates that you will be changing state in
* such a way that you would never ever want it to be written back to the
* storage.
*/
public function makeEphemeral() {
$this->__ephemeral = true;
return $this;
}
private function isEphemeralCheck() {
if ($this->__ephemeral) {
throw new LiskEphemeralObjectException();
}
}
/**
* Persist this object to the database. In most cases, this is the only
* method you need to call to do writes. If the object has not yet been
* inserted this will do an insert; if it has, it will do an update.
*
* @return this
*
* @task save
*/
public function save() {
if ($this->shouldInsertWhenSaved()) {
return $this->insert();
} else {
return $this->update();
}
}
/**
* Save this object, forcing the query to use REPLACE regardless of object
* state.
*
* @return this
*
* @task save
*/
public function replace() {
$this->isEphemeralCheck();
return $this->insertRecordIntoDatabase('REPLACE');
}
/**
* Save this object, forcing the query to use INSERT regardless of object
* state.
*
* @return this
*
* @task save
*/
public function insert() {
$this->isEphemeralCheck();
return $this->insertRecordIntoDatabase('INSERT');
}
/**
* Save this object, forcing the query to use UPDATE regardless of object
* state.
*
* @return this
*
* @task save
*/
public function update() {
$this->isEphemeralCheck();
$use_locks = $this->getConfigOption(self::CONFIG_OPTIMISTIC_LOCKS);
$this->willSaveObject();
$data = $this->getPropertyValues();
if ($this->getConfigOption(self::CONFIG_PARTIAL_OBJECTS)) {
$data = array_intersect_key($data, $this->__dirtyFields);
}
$this->willWriteData($data);
$map = array();
foreach ($data as $k => $v) {
if ($use_locks && $k == 'version') {
continue;
}
$map[$k] = $v;
}
$conn = $this->establishConnection('w');
foreach ($map as $key => $value) {
$map[$key] = qsprintf($conn, '%C = %ns', $key, $value);
}
$map = implode(', ', $map);
if ($use_locks) {
$conn->query(
'UPDATE %T SET %Q, version = version + 1 WHERE %C = %d AND %C = %d',
$this->getTableName(),
$map,
$this->getIDKeyForUse(),
$this->getID(),
'version',
$this->getVersion());
if ($conn->getAffectedRows() !== 1) {
throw new AphrontQueryObjectMissingException($use_locks);
}
$this->setVersion($this->getVersion() + 1);
} else {
$id = $this->getID();
$conn->query(
'UPDATE %T SET %Q WHERE %C = '.(is_int($id) ? '%d' : '%s'),
$this->getTableName(),
$map,
$this->getIDKeyForUse(),
$id);
// We can't detect a missing object because updating an object without
// changing any values doesn't affect rows. We could jiggle timestamps
// to catch this for objects which track them if we wanted.
}
$this->didWriteData();
if ($this->getConfigOption(self::CONFIG_PARTIAL_OBJECTS)) {
$this->resetDirtyFields();
}
return $this;
}
/**
* Delete this object, permanently.
*
* @return this
*
* @task save
*/
public function delete() {
$this->isEphemeralCheck();
$this->willDelete();
$conn = $this->establishConnection('w');
$conn->query(
'DELETE FROM %T WHERE %C = %d',
$this->getTableName(),
$this->getIDKeyForUse(),
$this->getID());
$this->didDelete();
return $this;
}
/**
* Internal implementation of INSERT and REPLACE.
*
* @param const Either "INSERT" or "REPLACE", to force the desired mode.
*
* @task save
*/
protected function insertRecordIntoDatabase($mode) {
$this->willSaveObject();
$data = $this->getPropertyValues();
$id_mechanism = $this->getConfigOption(self::CONFIG_IDS);
switch ($id_mechanism) {
case self::IDS_AUTOINCREMENT:
// If we are using autoincrement IDs, let MySQL assign the value for the
// ID column, if it is empty. If the caller has explicitly provided a
// value, use it.
$id_key = $this->getIDKeyForUse();
if (empty($data[$id_key])) {
unset($data[$id_key]);
}
break;
case self::IDS_PHID:
if (empty($data[$this->getIDKeyForUse()])) {
$phid = $this->generatePHID();
$this->setID($phid);
$data[$this->getIDKeyForUse()] = $phid;
}
break;
case self::IDS_MANUAL:
break;
default:
throw new Exception('Unknown CONFIG_IDs mechanism!');
}
if ($this->getConfigOption(self::CONFIG_OPTIMISTIC_LOCKS)) {
$data['version'] = 0;
}
$this->willWriteData($data);
$conn = $this->establishConnection('w');
$columns = array_keys($data);
foreach ($data as $key => $value) {
$data[$key] = qsprintf($conn, '%ns', $value);
}
$data = implode(', ', $data);
$conn->query(
'%Q INTO %T (%LC) VALUES (%Q)',
$mode,
$this->getTableName(),
$columns,
$data);
// Update the object with the initial Version value
if ($this->getConfigOption(self::CONFIG_OPTIMISTIC_LOCKS)) {
$this->setVersion(0);
}
// Only use the insert id if this table is using auto-increment ids
if ($id_mechanism === self::IDS_AUTOINCREMENT) {
$this->setID($conn->getInsertID());
}
$this->didWriteData();
if ($this->getConfigOption(self::CONFIG_PARTIAL_OBJECTS)) {
$this->resetDirtyFields();
}
return $this;
}
/**
* Method used to determine whether to insert or update when saving.
*
* @return bool true if the record should be inserted
*/
protected function shouldInsertWhenSaved() {
$key_type = $this->getConfigOption(self::CONFIG_IDS);
$use_locks = $this->getConfigOption(self::CONFIG_OPTIMISTIC_LOCKS);
if ($key_type == self::IDS_MANUAL) {
if ($use_locks) {
// If we are manually keyed and the object has a version (which means
// that it has been saved to the DB before), do an update, otherwise
// perform an insert.
if ($this->getID() && $this->getVersion() !== null) {
return false;
} else {
return true;
}
} else {
throw new Exception(
'You are not using optimistic locks, but are using manual IDs. You '.
'must override the shouldInsertWhenSaved() method to properly '.
'detect when to insert a new record.');
}
} else {
return !$this->getID();
}
}
/* -( Hooks and Callbacks )------------------------------------------------ */
/**
* Retrieve the database table name. By default, this is the class name.
*
* @return string Table name for object storage.
*
* @task hook
*/
public function getTableName() {
return get_class($this);
}
/**
* Helper: Whether this class is configured to use PHIDs as the primary ID.
* @task internal
*/
private function isPHIDPrimaryID() {
return ($this->getConfigOption(self::CONFIG_IDS) === self::IDS_PHID);
}
/**
* Retrieve the primary key column, "id" by default. If you can not
* reasonably name your ID column "id", override this method.
*
* @return string Name of the ID column.
*
* @task hook
*/
public function getIDKey() {
return
$this->isPHIDPrimaryID() ?
'phid' :
'id';
}
protected function getIDKeyForUse() {
$id_key = $this->getIDKey();
if (!$id_key) {
throw new Exception(
"This DAO does not have a single-part primary key. The method you ".
"called requires a single-part primary key.");
}
return $id_key;
}
/**
* Generate a new PHID, used by CONFIG_AUX_PHID and IDS_PHID.
*
* @return phid Unique, newly allocated PHID.
*
* @task hook
*/
protected function generatePHID() {
throw new Exception(
"To use CONFIG_AUX_PHID or IDS_PHID, you need to overload ".
"generatePHID() to perform PHID generation.");
}
/**
* Hook to apply serialization or validation to data before it is written to
* the database. See also willReadData().
*
* @task hook
*/
protected function willWriteData(array &$data) {
$this->applyLiskDataSerialization($data, false);
}
/**
* Hook to perform actions after data has been written to the database.
*
* @task hook
*/
protected function didWriteData() {}
/**
* Hook to make internal object state changes prior to INSERT, REPLACE or
* UPDATE.
*
* @task hook
*/
protected function willSaveObject() {
$use_timestamps = $this->getConfigOption(self::CONFIG_TIMESTAMPS);
if ($use_timestamps) {
if (!$this->getDateCreated()) {
$this->setDateCreated(time());
}
$this->setDateModified(time());
}
if (($this->isPHIDPrimaryID() && !$this->getID())) {
// If PHIDs are the primary ID, the subclass could have overridden the
// name of the ID column.
$this->setID($this->generatePHID());
} else if ($this->getConfigOption(self::CONFIG_AUX_PHID) &&
!$this->getPHID()) {
// The subclass could still want PHIDs.
$this->setPHID($this->generatePHID());
}
}
/**
* Hook to apply serialization or validation to data as it is read from the
* database. See also willWriteData().
*
* @task hook
*/
protected function willReadData(array &$data) {
$this->applyLiskDataSerialization($data, $deserialize = true);
}
/**
* Hook to perform an action on data after it is read from the database.
*
* @task hook
*/
protected function didReadData() {}
/**
* Hook to perform an action before the deletion of an object.
*
* @task hook
*/
protected function willDelete() {}
/**
* Hook to perform an action after the deletion of an object.
*
* @task hook
*/
protected function didDelete() {}
/**
* Reads the value from a field. Override this method for custom behavior
* of getField() instead of overriding getField directly.
*
* @param string Canonical field name
* @return mixed Value of the field
*
* @task hook
*/
protected function readField($field) {
if (isset($this->$field)) {
return $this->$field;
}
return null;
}
/**
* Writes a value to a field. Override this method for custom behavior of
* setField($value) instead of overriding setField directly.
*
* @param string Canonical field name
* @param mixed Value to write
*
* @task hook
*/
protected function writeField($field, $value) {
$this->$field = $value;
}
/* -( Manging Transactions )----------------------------------------------- */
/**
* Increase transaction stack depth.
*
* @return this
*/
public function openTransaction() {
$this->establishConnection('w')->openTransaction();
return $this;
}
/**
* Decrease transaction stack depth, saving work.
*
* @return this
*/
public function saveTransaction() {
$this->establishConnection('w')->saveTransaction();
return $this;
}
/**
* Decrease transaction stack depth, discarding work.
*
* @return this
*/
public function killTransaction() {
$this->establishConnection('w')->killTransaction();
return $this;
}
/**
* Begins read-locking selected rows with SELECT ... FOR UPDATE, so that
* other connections can not read them (this is an enormous oversimplification
* of FOR UPDATE semantics; consult the MySQL documentation for details). To
* end read locking, call @{method:endReadLocking}. For example:
*
* $beach->openTransaction();
* $beach->beginReadLocking();
*
* $beach->reload();
* $beach->setGrainsOfSand($beach->getGrainsOfSand() + 1);
* $beach->save();
*
* $beach->endReadLocking();
* $beach->saveTransaction();
*
* @return this
* @task xaction
*/
public function beginReadLocking() {
$this->establishConnection('w')->beginReadLocking();
return $this;
}
/**
* Ends read-locking that began at an earlier @{method:beginReadLocking} call.
*
* @return this
* @task xaction
*/
public function endReadLocking() {
$this->establishConnection('w')->endReadLocking();
return $this;
}
/**
* Begins write-locking selected rows with SELECT ... LOCK IN SHARE MODE, so
* that other connections can not update or delete them (this is an
* oversimplification of LOCK IN SHARE MODE semantics; consult the
* MySQL documentation for details). To end write locking, call
* @{method:endWriteLocking}.
*
* @return this
* @task xaction
*/
public function beginWriteLocking() {
$this->establishConnection('w')->beginWriteLocking();
return $this;
}
/**
* Ends write-locking that began at an earlier @{method:beginWriteLocking}
* call.
*
* @return this
* @task xaction
*/
public function endWriteLocking() {
$this->establishConnection('w')->endWriteLocking();
return $this;
}
/* -( Isolation )---------------------------------------------------------- */
/**
* @task isolate
*/
public static function beginIsolateAllLiskEffectsToCurrentProcess() {
self::$processIsolationLevel++;
}
/**
* @task isolate
*/
public static function endIsolateAllLiskEffectsToCurrentProcess() {
self::$processIsolationLevel--;
if (self::$processIsolationLevel < 0) {
throw new Exception(
"Lisk process isolation level was reduced below 0.");
}
}
/**
* @task isolate
*/
public static function shouldIsolateAllLiskEffectsToCurrentProcess() {
return (bool)self::$processIsolationLevel;
}
/**
* @task isolate
*/
private function establishIsolatedConnection($mode) {
$config = array();
return new AphrontIsolatedDatabaseConnection($config);
}
/**
* @task isolate
*/
public static function beginIsolateAllLiskEffectsToTransactions() {
if (self::$transactionIsolationLevel === 0) {
self::closeAllConnections();
}
self::$transactionIsolationLevel++;
}
/**
* @task isolate
*/
public static function endIsolateAllLiskEffectsToTransactions() {
self::$transactionIsolationLevel--;
if (self::$transactionIsolationLevel < 0) {
throw new Exception(
"Lisk transaction isolation level was reduced below 0.");
} else if (self::$transactionIsolationLevel == 0) {
foreach (self::$connections as $key => $conn) {
if ($conn) {
$conn->killTransaction();
}
}
self::closeAllConnections();
}
}
/**
* @task isolate
*/
public static function shouldIsolateAllLiskEffectsToTransactions() {
return (bool)self::$transactionIsolationLevel;
}
public static function closeAllConnections() {
self::$connections = array();
}
/* -( Utilities )---------------------------------------------------------- */
/**
* Applies configured serialization to a dictionary of values.
*
* @task util
*/
protected function applyLiskDataSerialization(array &$data, $deserialize) {
$serialization = $this->getConfigOption(self::CONFIG_SERIALIZATION);
if ($serialization) {
foreach (array_intersect_key($serialization, $data) as $col => $format) {
switch ($format) {
case self::SERIALIZATION_NONE:
break;
case self::SERIALIZATION_PHP:
if ($deserialize) {
$data[$col] = unserialize($data[$col]);
} else {
$data[$col] = serialize($data[$col]);
}
break;
case self::SERIALIZATION_JSON:
if ($deserialize) {
$data[$col] = json_decode($data[$col], true);
} else {
$data[$col] = json_encode($data[$col]);
}
break;
default:
throw new Exception("Unknown serialization format '{$format}'.");
}
}
}
}
/**
* Resets the dirty fields (fields which need to be written on next save/
* update/insert/replace). If this DAO has timestamps, the modified time
* is always a dirty field.
*
* @task util
*/
private function resetDirtyFields() {
$this->__dirtyFields = array();
if ($this->getConfigOption(self::CONFIG_TIMESTAMPS)) {
$this->__dirtyFields['dateModified'] = true;
}
}
/**
* Black magic. Builds implied get*() and set*() for all properties.
*
* @param string Method name.
* @param list Argument vector.
* @return mixed get*() methods return the property value. set*() methods
* return $this.
* @task util
*/
public function __call($method, $args) {
// NOTE: This method is very performance-sensitive (many thousands of calls
// per page on some pages), and thus has some silliness in the name of
// optimizations.
static $dispatch_map = array();
static $partial = null;
if ($partial === null) {
$partial = $this->getConfigOption(self::CONFIG_PARTIAL_OBJECTS);
}
if ($method[0] === 'g') {
if (isset($dispatch_map[$method])) {
$property = $dispatch_map[$method];
} else {
if (substr($method, 0, 3) !== 'get') {
throw new Exception("Unable to resolve method '{$method}'!");
}
$property = substr($method, 3);
if (!($property = $this->checkProperty($property))) {
throw new Exception("Bad getter call: {$method}");
}
$dispatch_map[$method] = $property;
}
if ($partial && isset($this->__missingFields[$property])) {
throw new Exception("Cannot get field that wasn't loaded: {$property}");
}
return $this->readField($property);
}
if ($method[0] === 's') {
if (isset($dispatch_map[$method])) {
$property = $dispatch_map[$method];
} else {
if (substr($method, 0, 3) !== 'set') {
throw new Exception("Unable to resolve method '{$method}'!");
}
$property = substr($method, 3);
$property = $this->checkProperty($property);
if (!$property) {
throw new Exception("Bad setter call: {$method}");
}
if ($property == 'ID') {
$property = $this->getIDKeyForUse();
}
$dispatch_map[$method] = $property;
}
if ($partial) {
// Accept writes to fields that weren't initially loaded
unset($this->__missingFields[$property]);
$this->__dirtyFields[$property] = true;
}
$this->writeField($property, $args[0]);
return $this;
}
throw new Exception("Unable to resolve method '{$method}'.");
}
}

File Metadata

Mime Type
text/x-diff
Expires
Fri, Aug 15, 2:17 AM (3 d, 16 h ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
202367
Default Alt Text
(219 KB)

Event Timeline