Page MenuHomestyx hydra

No OneTemporary

diff --git a/.divinerconfig b/.divinerconfig
index c765720f12..88c73c168f 100644
--- a/.divinerconfig
+++ b/.divinerconfig
@@ -1,19 +1,23 @@
{
"name" : "Phabricator",
"src_base" : "https://github.com/facebook/phabricator/blob/master",
"groups" : {
"intro" : "Introduction",
"install" : "Installing",
"config" : "Configuration",
"userguide" : "Application User Guides",
"differential" : "Differential (Code Review)",
"diffusion" : "Diffusion (Repository Browser)",
"maniphest" : "Maniphest (Task Tracking)",
"celerity" : "Celerity (CSS/JS Management)",
"aphront" : "Aphront (Web Stack)",
"console" : "DarkConsole (Debugging Console)",
"storage" : "Storage"
- }
+ },
+ "engines" : [
+ ["DivinerArticleEngine", {}],
+ ["DivinerXHPEngine", {}]
+ ]
}
diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php
index a5823a6c62..41383b0a97 100644
--- a/src/__phutil_library_map__.php
+++ b/src/__phutil_library_map__.php
@@ -1,535 +1,536 @@
<?php
/**
* This file is automatically generated. Use 'phutil_mapper.php' to rebuild it.
* @generated
*/
phutil_register_library_map(array(
'class' =>
array(
'Aphront400Response' => 'aphront/response/400',
'Aphront404Response' => 'aphront/response/404',
'AphrontAjaxResponse' => 'aphront/response/ajax',
'AphrontApplicationConfiguration' => 'aphront/applicationconfiguration',
'AphrontController' => 'aphront/controller',
'AphrontDatabaseConnection' => 'storage/connection/base',
'AphrontDefaultApplicationConfiguration' => 'aphront/default/configuration',
'AphrontDefaultApplicationController' => 'aphront/default/controller',
'AphrontDialogResponse' => 'aphront/response/dialog',
'AphrontDialogView' => 'view/dialog',
'AphrontErrorView' => 'view/form/error',
'AphrontException' => 'aphront/exception/base',
'AphrontFileResponse' => 'aphront/response/file',
'AphrontFormCheckboxControl' => 'view/form/control/checkbox',
'AphrontFormControl' => 'view/form/control/base',
'AphrontFormDividerControl' => 'view/form/control/divider',
'AphrontFormFileControl' => 'view/form/control/file',
'AphrontFormMarkupControl' => 'view/form/control/markup',
'AphrontFormPasswordControl' => 'view/form/control/password',
'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',
'AphrontFormTokenizerControl' => 'view/form/control/tokenizer',
'AphrontFormView' => 'view/form/base',
'AphrontHeadsupActionListView' => 'view/layout/headsup/actionlist',
'AphrontHeadsupActionView' => 'view/layout/headsup/action',
'AphrontMySQLDatabaseConnection' => 'storage/connection/mysql',
'AphrontNullView' => 'view/null',
'AphrontPageView' => 'view/page/base',
'AphrontPanelView' => 'view/layout/panel',
'AphrontQueryConnectionException' => 'storage/exception/connection',
'AphrontQueryConnectionLostException' => 'storage/exception/connectionlost',
'AphrontQueryCountException' => 'storage/exception/count',
'AphrontQueryDuplicateKeyException' => 'storage/exception/duplicatekey',
'AphrontQueryException' => 'storage/exception/base',
'AphrontQueryObjectMissingException' => 'storage/exception/objectmissing',
'AphrontQueryParameterException' => 'storage/exception/parameter',
'AphrontQueryRecoverableException' => 'storage/exception/recoverable',
'AphrontRedirectException' => 'aphront/exception/redirect',
'AphrontRedirectResponse' => 'aphront/response/redirect',
'AphrontRequest' => 'aphront/request',
'AphrontRequestFailureView' => 'view/page/failure',
'AphrontResponse' => 'aphront/response/base',
'AphrontSideNavView' => 'view/layout/sidenav',
'AphrontTableView' => 'view/control/table',
'AphrontURIMapper' => 'aphront/mapper',
'AphrontView' => 'view/base',
'AphrontWebpageResponse' => 'aphront/response/webpage',
'CelerityAPI' => 'infrastructure/celerity/api',
'CelerityResourceController' => 'infrastructure/celerity/controller',
'CelerityResourceMap' => 'infrastructure/celerity/map',
'CelerityStaticResourceResponse' => 'infrastructure/celerity/response',
'ConduitAPIMethod' => 'applications/conduit/method/base',
'ConduitAPIRequest' => 'applications/conduit/protocol/request',
'ConduitAPI_conduit_connect_Method' => 'applications/conduit/method/conduit/connect',
'ConduitAPI_conduit_ping_Method' => 'applications/conduit/method/conduit/ping',
'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_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_markcommitted_Method' => 'applications/conduit/method/differential/markcommitted',
'ConduitAPI_differential_parsecommitmessage_Method' => 'applications/conduit/method/differential/parsecommitmessage',
'ConduitAPI_differential_setdiffproperty_Method' => 'applications/conduit/method/differential/setdiffproperty',
'ConduitAPI_differential_updaterevision_Method' => 'applications/conduit/method/differential/updaterevision',
'ConduitAPI_file_upload_Method' => 'applications/conduit/method/file/upload',
'ConduitAPI_user_find_Method' => 'applications/conduit/method/user/find',
'ConduitException' => 'applications/conduit/protocol/exception',
'DarkConsole' => 'aphront/console/api',
'DarkConsoleConfigPlugin' => 'aphront/console/plugin/config',
'DarkConsoleController' => 'aphront/console/controller',
'DarkConsoleCore' => 'aphront/console/core',
'DarkConsoleErrorLogPlugin' => 'aphront/console/plugin/errorlog',
'DarkConsoleErrorLogPluginAPI' => 'aphront/console/plugin/errorlog/api',
'DarkConsolePlugin' => 'aphront/console/plugin/base',
'DarkConsoleRequestPlugin' => 'aphront/console/plugin/request',
'DarkConsoleServicesPlugin' => 'aphront/console/plugin/services',
'DarkConsoleServicesPluginAPI' => 'aphront/console/plugin/services/api',
'DarkConsoleXHProfPlugin' => 'aphront/console/plugin/xhprof',
'DarkConsoleXHProfPluginAPI' => 'aphront/console/plugin/xhprof/api',
'DifferentialAction' => 'applications/differential/constants/action',
'DifferentialAddCommentView' => 'applications/differential/view/addcomment',
'DifferentialAttachController' => 'applications/differential/controller/attach',
'DifferentialCCWelcomeMail' => 'applications/differential/mail/ccwelcome',
'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',
'DifferentialCommitMessage' => 'applications/differential/parser/commitmessage',
'DifferentialCommitMessageData' => 'applications/differential/data/commitmessage',
'DifferentialCommitMessageParserException' => 'applications/differential/parser/commitmessage/exception',
'DifferentialController' => 'applications/differential/controller/base',
'DifferentialDAO' => 'applications/differential/storage/base',
'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',
'DifferentialHunk' => 'applications/differential/storage/hunk',
'DifferentialInlineComment' => 'applications/differential/storage/inlinecomment',
'DifferentialInlineCommentEditController' => 'applications/differential/controller/inlinecommentedit',
'DifferentialInlineCommentPreviewController' => 'applications/differential/controller/inlinecommentpreview',
'DifferentialInlineCommentView' => 'applications/differential/view/inlinecomment',
'DifferentialLintStatus' => 'applications/differential/constants/lintstatus',
'DifferentialMail' => 'applications/differential/mail/base',
'DifferentialMarkupEngineFactory' => 'applications/differential/parser/markup',
'DifferentialNewDiffMail' => 'applications/differential/mail/newdiff',
'DifferentialReviewRequestMail' => 'applications/differential/mail/reviewrequest',
'DifferentialRevision' => 'applications/differential/storage/revision',
'DifferentialRevisionCommentListView' => 'applications/differential/view/revisioncommentlist',
'DifferentialRevisionCommentView' => 'applications/differential/view/revisioncomment',
'DifferentialRevisionControlSystem' => 'applications/differential/constants/revisioncontrolsystem',
'DifferentialRevisionDetailView' => 'applications/differential/view/revisiondetail',
'DifferentialRevisionEditController' => 'applications/differential/controller/revisionedit',
'DifferentialRevisionEditor' => 'applications/differential/editor/revision',
'DifferentialRevisionListController' => 'applications/differential/controller/revisionlist',
'DifferentialRevisionListData' => 'applications/differential/data/revisionlist',
'DifferentialRevisionStatus' => 'applications/differential/constants/revisionstatus',
'DifferentialRevisionUpdateHistoryView' => 'applications/differential/view/revisionupdatehistory',
'DifferentialRevisionViewController' => 'applications/differential/controller/revisionview',
'DifferentialSubscribeController' => 'applications/differential/controller/subscribe',
'DifferentialUnitStatus' => 'applications/differential/constants/unitstatus',
'Javelin' => 'infrastructure/javelin/api',
'LiskDAO' => 'storage/lisk/dao',
'ManiphestController' => 'applications/maniphest/controller/base',
'ManiphestDAO' => 'applications/maniphest/storage/base',
'ManiphestTask' => 'applications/maniphest/storage/task',
'ManiphestTaskDetailController' => 'applications/maniphest/controller/taskdetail',
'ManiphestTaskEditController' => 'applications/maniphest/controller/taskedit',
'ManiphestTaskListController' => 'applications/maniphest/controller/tasklist',
'ManiphestTaskListView' => 'applications/maniphest/view/tasklist',
'ManiphestTaskPriority' => 'applications/maniphest/constants/priority',
'ManiphestTaskSelectorSearchController' => 'applications/maniphest/controller/taskselectorsearch',
'ManiphestTaskStatus' => 'applications/maniphest/constants/status',
'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',
'ManiphestTransactionSaveController' => 'applications/maniphest/controller/transactionsave',
'ManiphestTransactionType' => 'applications/maniphest/constants/transactiontype',
'Phabricator404Controller' => 'applications/base/controller/404',
'PhabricatorAuthController' => 'applications/auth/controller/base',
'PhabricatorConduitAPIController' => 'applications/conduit/controller/api',
'PhabricatorConduitConnectionLog' => 'applications/conduit/storage/connectionlog',
'PhabricatorConduitConsoleController' => 'applications/conduit/controller/console',
'PhabricatorConduitController' => 'applications/conduit/controller/base',
'PhabricatorConduitDAO' => 'applications/conduit/storage/base',
'PhabricatorConduitLogController' => 'applications/conduit/controller/log',
'PhabricatorConduitMethodCallLog' => 'applications/conduit/storage/methodcalllog',
'PhabricatorController' => 'applications/base/controller/base',
'PhabricatorDirectoryCategory' => 'applications/directory/storage/category',
'PhabricatorDirectoryCategoryDeleteController' => 'applications/directory/controller/categorydelete',
'PhabricatorDirectoryCategoryEditController' => 'applications/directory/controller/categoryedit',
'PhabricatorDirectoryCategoryListController' => 'applications/directory/controller/categorylist',
'PhabricatorDirectoryController' => 'applications/directory/controller/base',
'PhabricatorDirectoryDAO' => 'applications/directory/storage/base',
'PhabricatorDirectoryItem' => 'applications/directory/storage/item',
'PhabricatorDirectoryItemDeleteController' => 'applications/directory/controller/itemdelete',
'PhabricatorDirectoryItemEditController' => 'applications/directory/controller/itemedit',
'PhabricatorDirectoryItemListController' => 'applications/directory/controller/itemlist',
'PhabricatorDirectoryMainController' => 'applications/directory/controller/main',
'PhabricatorDraft' => 'applications/draft/storage/draft',
'PhabricatorDraftDAO' => 'applications/draft/storage/base',
'PhabricatorEmailLoginController' => 'applications/auth/controller/email',
'PhabricatorEmailTokenController' => 'applications/auth/controller/emailtoken',
'PhabricatorEnv' => 'infrastructure/env',
'PhabricatorFile' => 'applications/files/storage/file',
'PhabricatorFileController' => 'applications/files/controller/base',
'PhabricatorFileDAO' => 'applications/files/storage/base',
'PhabricatorFileListController' => 'applications/files/controller/list',
'PhabricatorFileStorageBlob' => 'applications/files/storage/storageblob',
'PhabricatorFileURI' => 'applications/files/uri',
'PhabricatorFileUploadController' => 'applications/files/controller/upload',
'PhabricatorFileViewController' => 'applications/files/controller/view',
'PhabricatorHandleObjectSelectorDataView' => 'applications/phid/handle/view/selector',
'PhabricatorLiskDAO' => 'applications/base/storage/lisk',
'PhabricatorLoginController' => 'applications/auth/controller/login',
'PhabricatorLogoutController' => 'applications/auth/controller/logout',
'PhabricatorMailImplementationAdapter' => 'applications/metamta/adapter/base',
'PhabricatorMailImplementationAmazonSESAdapter' => 'applications/metamta/adapter/amazonses',
'PhabricatorMailImplementationPHPMailerLiteAdapter' => 'applications/metamta/adapter/phpmailerlite',
'PhabricatorMetaMTAController' => 'applications/metamta/controller/base',
'PhabricatorMetaMTADAO' => 'applications/metamta/storage/base',
'PhabricatorMetaMTADaemon' => 'applications/metamta/daemon/mta',
'PhabricatorMetaMTAListController' => 'applications/metamta/controller/list',
'PhabricatorMetaMTAMail' => 'applications/metamta/storage/mail',
'PhabricatorMetaMTAMailingList' => 'applications/metamta/storage/mailinglist',
'PhabricatorMetaMTAMailingListEditController' => 'applications/metamta/controller/mailinglistedit',
'PhabricatorMetaMTAMailingListsController' => 'applications/metamta/controller/mailinglists',
'PhabricatorMetaMTASendController' => 'applications/metamta/controller/send',
'PhabricatorMetaMTAViewController' => 'applications/metamta/controller/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',
'PhabricatorOAuthProviderFacebook' => 'applications/auth/oauth/provider/facebook',
'PhabricatorOAuthProviderGithub' => 'applications/auth/oauth/provider/github',
'PhabricatorOAuthRegistrationController' => 'applications/auth/controller/oauthregistration/base',
'PhabricatorOAuthUnlinkController' => 'applications/auth/controller/unlink',
'PhabricatorObjectHandle' => 'applications/phid/handle',
'PhabricatorObjectHandleData' => 'applications/phid/handle/data',
'PhabricatorObjectSelectorDialog' => 'view/control/objectselector',
'PhabricatorPHID' => 'applications/phid/storage/phid',
'PhabricatorPHIDAllocateController' => 'applications/phid/controller/allocate',
+ 'PhabricatorPHIDConstants' => 'applications/phid/constants',
'PhabricatorPHIDController' => 'applications/phid/controller/base',
'PhabricatorPHIDDAO' => 'applications/phid/storage/base',
'PhabricatorPHIDListController' => 'applications/phid/controller/list',
'PhabricatorPHIDLookupController' => 'applications/phid/controller/lookup',
'PhabricatorPHIDType' => 'applications/phid/storage/type',
'PhabricatorPHIDTypeEditController' => 'applications/phid/controller/typeedit',
'PhabricatorPHIDTypeListController' => 'applications/phid/controller/typelist',
'PhabricatorPeopleController' => 'applications/people/controller/base',
'PhabricatorPeopleEditController' => 'applications/people/controller/edit',
'PhabricatorPeopleListController' => 'applications/people/controller/list',
'PhabricatorPeopleProfileController' => 'applications/people/controller/profile',
'PhabricatorPeopleProfileEditController' => 'applications/people/controller/profileedit',
'PhabricatorProject' => 'applications/project/storage/project',
'PhabricatorProjectAffiliation' => 'applications/project/storage/affiliation',
'PhabricatorProjectAffiliationEditController' => 'applications/project/controller/editaffiliation',
'PhabricatorProjectController' => 'applications/project/controller/base',
'PhabricatorProjectDAO' => 'applications/project/storage/base',
'PhabricatorProjectEditController' => 'applications/project/controller/edit',
'PhabricatorProjectListController' => 'applications/project/controller/list',
'PhabricatorProjectProfile' => 'applications/project/storage/profile',
'PhabricatorProjectProfileController' => 'applications/project/controller/profile',
'PhabricatorRemarkupRuleDifferential' => 'infrastructure/markup/remarkup/markuprule/differential',
'PhabricatorRemarkupRuleManiphest' => 'infrastructure/markup/remarkup/markuprule/maniphest',
'PhabricatorRepository' => 'applications/repository/storage/repository',
'PhabricatorRepositoryController' => 'applications/repository/controller/base',
'PhabricatorRepositoryCreateController' => 'applications/repository/controller/create',
'PhabricatorRepositoryDAO' => 'applications/repository/storage/base',
'PhabricatorRepositoryEditController' => 'applications/repository/controller/edit',
'PhabricatorRepositoryGitHubNotification' => 'applications/repository/storage/githubnotification',
'PhabricatorRepositoryGitHubPostReceiveController' => 'applications/repository/controller/github-post-receive',
'PhabricatorRepositoryListController' => 'applications/repository/controller/list',
'PhabricatorSearchAbstractDocument' => 'applications/search/index/abstractdocument',
'PhabricatorSearchBaseController' => 'applications/search/controller/base',
'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',
'PhabricatorSearchExecutor' => 'applications/search/execute/base',
'PhabricatorSearchField' => 'applications/search/constants/field',
'PhabricatorSearchManiphestIndexer' => 'applications/search/index/indexer/maniphest',
'PhabricatorSearchMySQLExecutor' => 'applications/search/execute/mysql',
'PhabricatorSearchQuery' => 'applications/search/storage/query',
'PhabricatorSearchRelationship' => 'applications/search/constants/relationship',
'PhabricatorStandardPageView' => 'view/page/standard',
'PhabricatorTypeaheadCommonDatasourceController' => 'applications/typeahead/controller/common',
'PhabricatorTypeaheadDatasourceController' => 'applications/typeahead/controller/base',
'PhabricatorUser' => 'applications/people/storage/user',
'PhabricatorUserDAO' => 'applications/people/storage/base',
'PhabricatorUserOAuthInfo' => 'applications/people/storage/useroauthinfo',
'PhabricatorUserProfile' => 'applications/people/storage/profile',
'PhabricatorUserSettingsController' => 'applications/people/controller/settings',
'PhabricatorXHProfController' => 'applications/xhprof/controller/base',
'PhabricatorXHProfProfileController' => 'applications/xhprof/controller/profile',
'PhabricatorXHProfProfileSymbolView' => 'applications/xhprof/view/symbol',
'PhabricatorXHProfProfileTopLevelView' => 'applications/xhprof/view/toplevel',
),
'function' =>
array(
'_qsprintf_check_scalar_type' => 'storage/qsprintf',
'_qsprintf_check_type' => 'storage/qsprintf',
'celerity_generate_unique_node_id' => 'infrastructure/celerity/api',
'celerity_register_resource_map' => 'infrastructure/celerity/map',
'javelin_render_tag' => 'infrastructure/javelin/markup',
'phabricator_format_relative_time' => 'view/utils',
'phabricator_format_timestamp' => 'view/utils',
'phabricator_format_units_generic' => 'view/utils',
'phabricator_render_form' => 'infrastructure/javelin/markup',
'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(
'Aphront400Response' => 'AphrontResponse',
'Aphront404Response' => 'AphrontResponse',
'AphrontAjaxResponse' => 'AphrontResponse',
'AphrontDefaultApplicationConfiguration' => 'AphrontApplicationConfiguration',
'AphrontDefaultApplicationController' => 'AphrontController',
'AphrontDialogResponse' => 'AphrontResponse',
'AphrontDialogView' => 'AphrontView',
'AphrontErrorView' => 'AphrontView',
'AphrontFileResponse' => 'AphrontResponse',
'AphrontFormCheckboxControl' => 'AphrontFormControl',
'AphrontFormControl' => 'AphrontView',
'AphrontFormDividerControl' => 'AphrontFormControl',
'AphrontFormFileControl' => 'AphrontFormControl',
'AphrontFormMarkupControl' => 'AphrontFormControl',
'AphrontFormPasswordControl' => 'AphrontFormControl',
'AphrontFormRecaptchaControl' => 'AphrontFormControl',
'AphrontFormSelectControl' => 'AphrontFormControl',
'AphrontFormStaticControl' => 'AphrontFormControl',
'AphrontFormSubmitControl' => 'AphrontFormControl',
'AphrontFormTextAreaControl' => 'AphrontFormControl',
'AphrontFormTextControl' => 'AphrontFormControl',
'AphrontFormTokenizerControl' => 'AphrontFormControl',
'AphrontFormView' => 'AphrontView',
'AphrontHeadsupActionListView' => 'AphrontView',
'AphrontHeadsupActionView' => 'AphrontView',
'AphrontMySQLDatabaseConnection' => 'AphrontDatabaseConnection',
'AphrontNullView' => 'AphrontView',
'AphrontPageView' => 'AphrontView',
'AphrontPanelView' => 'AphrontView',
'AphrontQueryConnectionException' => 'AphrontQueryException',
'AphrontQueryConnectionLostException' => 'AphrontQueryRecoverableException',
'AphrontQueryCountException' => 'AphrontQueryException',
'AphrontQueryDuplicateKeyException' => 'AphrontQueryException',
'AphrontQueryObjectMissingException' => 'AphrontQueryException',
'AphrontQueryParameterException' => 'AphrontQueryException',
'AphrontQueryRecoverableException' => 'AphrontQueryException',
'AphrontRedirectException' => 'AphrontException',
'AphrontRedirectResponse' => 'AphrontResponse',
'AphrontRequestFailureView' => 'AphrontView',
'AphrontSideNavView' => 'AphrontView',
'AphrontTableView' => 'AphrontView',
'AphrontWebpageResponse' => 'AphrontResponse',
'CelerityResourceController' => 'AphrontController',
'ConduitAPI_conduit_connect_Method' => 'ConduitAPIMethod',
'ConduitAPI_conduit_ping_Method' => 'ConduitAPIMethod',
'ConduitAPI_differential_creatediff_Method' => 'ConduitAPIMethod',
'ConduitAPI_differential_createrevision_Method' => 'ConduitAPIMethod',
'ConduitAPI_differential_find_Method' => 'ConduitAPIMethod',
'ConduitAPI_differential_getcommitmessage_Method' => 'ConduitAPIMethod',
'ConduitAPI_differential_getcommitpaths_Method' => 'ConduitAPIMethod',
'ConduitAPI_differential_getdiff_Method' => 'ConduitAPIMethod',
'ConduitAPI_differential_markcommitted_Method' => 'ConduitAPIMethod',
'ConduitAPI_differential_parsecommitmessage_Method' => 'ConduitAPIMethod',
'ConduitAPI_differential_setdiffproperty_Method' => 'ConduitAPIMethod',
'ConduitAPI_differential_updaterevision_Method' => 'ConduitAPIMethod',
'ConduitAPI_file_upload_Method' => 'ConduitAPIMethod',
'ConduitAPI_user_find_Method' => 'ConduitAPIMethod',
'DarkConsoleConfigPlugin' => 'DarkConsolePlugin',
'DarkConsoleController' => 'PhabricatorController',
'DarkConsoleErrorLogPlugin' => 'DarkConsolePlugin',
'DarkConsoleRequestPlugin' => 'DarkConsolePlugin',
'DarkConsoleServicesPlugin' => 'DarkConsolePlugin',
'DarkConsoleXHProfPlugin' => 'DarkConsolePlugin',
'DifferentialAddCommentView' => 'AphrontView',
'DifferentialAttachController' => 'DifferentialController',
'DifferentialCCWelcomeMail' => 'DifferentialReviewRequestMail',
'DifferentialChangeset' => 'DifferentialDAO',
'DifferentialChangesetDetailView' => 'AphrontView',
'DifferentialChangesetListView' => 'AphrontView',
'DifferentialChangesetViewController' => 'DifferentialController',
'DifferentialComment' => 'DifferentialDAO',
'DifferentialCommentMail' => 'DifferentialMail',
'DifferentialCommentPreviewController' => 'DifferentialController',
'DifferentialCommentSaveController' => 'DifferentialController',
'DifferentialController' => 'PhabricatorController',
'DifferentialDAO' => 'PhabricatorLiskDAO',
'DifferentialDiff' => 'DifferentialDAO',
'DifferentialDiffContentMail' => 'DifferentialMail',
'DifferentialDiffCreateController' => 'DifferentialController',
'DifferentialDiffProperty' => 'DifferentialDAO',
'DifferentialDiffTableOfContentsView' => 'AphrontView',
'DifferentialDiffViewController' => 'DifferentialController',
'DifferentialHunk' => 'DifferentialDAO',
'DifferentialInlineComment' => 'DifferentialDAO',
'DifferentialInlineCommentEditController' => 'DifferentialController',
'DifferentialInlineCommentPreviewController' => 'DifferentialController',
'DifferentialInlineCommentView' => 'AphrontView',
'DifferentialNewDiffMail' => 'DifferentialReviewRequestMail',
'DifferentialReviewRequestMail' => 'DifferentialMail',
'DifferentialRevision' => 'DifferentialDAO',
'DifferentialRevisionCommentListView' => 'AphrontView',
'DifferentialRevisionCommentView' => 'AphrontView',
'DifferentialRevisionDetailView' => 'AphrontView',
'DifferentialRevisionEditController' => 'DifferentialController',
'DifferentialRevisionListController' => 'DifferentialController',
'DifferentialRevisionUpdateHistoryView' => 'AphrontView',
'DifferentialRevisionViewController' => 'DifferentialController',
'DifferentialSubscribeController' => 'DifferentialController',
'ManiphestController' => 'PhabricatorController',
'ManiphestDAO' => 'PhabricatorLiskDAO',
'ManiphestTask' => 'ManiphestDAO',
'ManiphestTaskDetailController' => 'ManiphestController',
'ManiphestTaskEditController' => 'ManiphestController',
'ManiphestTaskListController' => 'ManiphestController',
'ManiphestTaskListView' => 'AphrontView',
'ManiphestTaskSelectorSearchController' => 'ManiphestController',
'ManiphestTaskSummaryView' => 'AphrontView',
'ManiphestTransaction' => 'ManiphestDAO',
'ManiphestTransactionDetailView' => 'AphrontView',
'ManiphestTransactionListView' => 'AphrontView',
'ManiphestTransactionSaveController' => 'ManiphestController',
'Phabricator404Controller' => 'PhabricatorController',
'PhabricatorAuthController' => 'PhabricatorController',
'PhabricatorConduitAPIController' => 'PhabricatorConduitController',
'PhabricatorConduitConnectionLog' => 'PhabricatorConduitDAO',
'PhabricatorConduitConsoleController' => 'PhabricatorConduitController',
'PhabricatorConduitController' => 'PhabricatorController',
'PhabricatorConduitDAO' => 'PhabricatorLiskDAO',
'PhabricatorConduitLogController' => 'PhabricatorConduitController',
'PhabricatorConduitMethodCallLog' => 'PhabricatorConduitDAO',
'PhabricatorController' => 'AphrontController',
'PhabricatorDirectoryCategory' => 'PhabricatorDirectoryDAO',
'PhabricatorDirectoryCategoryDeleteController' => 'PhabricatorDirectoryController',
'PhabricatorDirectoryCategoryEditController' => 'PhabricatorDirectoryController',
'PhabricatorDirectoryCategoryListController' => 'PhabricatorDirectoryController',
'PhabricatorDirectoryController' => 'PhabricatorController',
'PhabricatorDirectoryDAO' => 'PhabricatorLiskDAO',
'PhabricatorDirectoryItem' => 'PhabricatorDirectoryDAO',
'PhabricatorDirectoryItemDeleteController' => 'PhabricatorDirectoryController',
'PhabricatorDirectoryItemEditController' => 'PhabricatorDirectoryController',
'PhabricatorDirectoryItemListController' => 'PhabricatorDirectoryController',
'PhabricatorDirectoryMainController' => 'PhabricatorDirectoryController',
'PhabricatorDraft' => 'PhabricatorDraftDAO',
'PhabricatorDraftDAO' => 'PhabricatorLiskDAO',
'PhabricatorEmailLoginController' => 'PhabricatorAuthController',
'PhabricatorEmailTokenController' => 'PhabricatorAuthController',
'PhabricatorFile' => 'PhabricatorFileDAO',
'PhabricatorFileController' => 'PhabricatorController',
'PhabricatorFileDAO' => 'PhabricatorLiskDAO',
'PhabricatorFileListController' => 'PhabricatorFileController',
'PhabricatorFileStorageBlob' => 'PhabricatorFileDAO',
'PhabricatorFileUploadController' => 'PhabricatorFileController',
'PhabricatorFileViewController' => 'PhabricatorFileController',
'PhabricatorLiskDAO' => 'LiskDAO',
'PhabricatorLoginController' => 'PhabricatorAuthController',
'PhabricatorLogoutController' => 'PhabricatorAuthController',
'PhabricatorMailImplementationAmazonSESAdapter' => 'PhabricatorMailImplementationPHPMailerLiteAdapter',
'PhabricatorMailImplementationPHPMailerLiteAdapter' => 'PhabricatorMailImplementationAdapter',
'PhabricatorMetaMTAController' => 'PhabricatorController',
'PhabricatorMetaMTADAO' => 'PhabricatorLiskDAO',
'PhabricatorMetaMTAListController' => 'PhabricatorMetaMTAController',
'PhabricatorMetaMTAMail' => 'PhabricatorMetaMTADAO',
'PhabricatorMetaMTAMailingList' => 'PhabricatorMetaMTADAO',
'PhabricatorMetaMTAMailingListEditController' => 'PhabricatorMetaMTAController',
'PhabricatorMetaMTAMailingListsController' => 'PhabricatorMetaMTAController',
'PhabricatorMetaMTASendController' => 'PhabricatorMetaMTAController',
'PhabricatorMetaMTAViewController' => 'PhabricatorMetaMTAController',
'PhabricatorOAuthDefaultRegistrationController' => 'PhabricatorOAuthRegistrationController',
'PhabricatorOAuthDiagnosticsController' => 'PhabricatorAuthController',
'PhabricatorOAuthFailureView' => 'AphrontView',
'PhabricatorOAuthLoginController' => 'PhabricatorAuthController',
'PhabricatorOAuthProviderFacebook' => 'PhabricatorOAuthProvider',
'PhabricatorOAuthProviderGithub' => 'PhabricatorOAuthProvider',
'PhabricatorOAuthRegistrationController' => 'PhabricatorAuthController',
'PhabricatorOAuthUnlinkController' => 'PhabricatorAuthController',
'PhabricatorPHID' => 'PhabricatorPHIDDAO',
'PhabricatorPHIDAllocateController' => 'PhabricatorPHIDController',
'PhabricatorPHIDController' => 'PhabricatorController',
'PhabricatorPHIDDAO' => 'PhabricatorLiskDAO',
'PhabricatorPHIDListController' => 'PhabricatorPHIDController',
'PhabricatorPHIDLookupController' => 'PhabricatorPHIDController',
'PhabricatorPHIDType' => 'PhabricatorPHIDDAO',
'PhabricatorPHIDTypeEditController' => 'PhabricatorPHIDController',
'PhabricatorPHIDTypeListController' => 'PhabricatorPHIDController',
'PhabricatorPeopleController' => 'PhabricatorController',
'PhabricatorPeopleEditController' => 'PhabricatorPeopleController',
'PhabricatorPeopleListController' => 'PhabricatorPeopleController',
'PhabricatorPeopleProfileController' => 'PhabricatorPeopleController',
'PhabricatorPeopleProfileEditController' => 'PhabricatorPeopleController',
'PhabricatorProject' => 'PhabricatorProjectDAO',
'PhabricatorProjectAffiliation' => 'PhabricatorProjectDAO',
'PhabricatorProjectAffiliationEditController' => 'PhabricatorProjectController',
'PhabricatorProjectController' => 'PhabricatorController',
'PhabricatorProjectDAO' => 'PhabricatorLiskDAO',
'PhabricatorProjectEditController' => 'PhabricatorProjectController',
'PhabricatorProjectListController' => 'PhabricatorProjectController',
'PhabricatorProjectProfile' => 'PhabricatorProjectDAO',
'PhabricatorProjectProfileController' => 'PhabricatorProjectController',
'PhabricatorRemarkupRuleDifferential' => 'PhutilRemarkupRule',
'PhabricatorRemarkupRuleManiphest' => 'PhutilRemarkupRule',
'PhabricatorRepository' => 'PhabricatorRepositoryDAO',
'PhabricatorRepositoryController' => 'PhabricatorController',
'PhabricatorRepositoryCreateController' => 'PhabricatorController',
'PhabricatorRepositoryDAO' => 'PhabricatorLiskDAO',
'PhabricatorRepositoryEditController' => 'PhabricatorController',
'PhabricatorRepositoryGitHubNotification' => 'PhabricatorRepositoryDAO',
'PhabricatorRepositoryGitHubPostReceiveController' => 'PhabricatorRepositoryController',
'PhabricatorRepositoryListController' => 'PhabricatorController',
'PhabricatorSearchBaseController' => 'PhabricatorController',
'PhabricatorSearchController' => 'PhabricatorSearchBaseController',
'PhabricatorSearchDAO' => 'PhabricatorLiskDAO',
'PhabricatorSearchDifferentialIndexer' => 'PhabricatorSearchDocumentIndexer',
'PhabricatorSearchDocument' => 'PhabricatorSearchDAO',
'PhabricatorSearchDocumentField' => 'PhabricatorSearchDAO',
'PhabricatorSearchDocumentRelationship' => 'PhabricatorSearchDAO',
'PhabricatorSearchManiphestIndexer' => 'PhabricatorSearchDocumentIndexer',
'PhabricatorSearchMySQLExecutor' => 'PhabricatorSearchExecutor',
'PhabricatorSearchQuery' => 'PhabricatorSearchDAO',
'PhabricatorStandardPageView' => 'AphrontPageView',
'PhabricatorTypeaheadCommonDatasourceController' => 'PhabricatorTypeaheadDatasourceController',
'PhabricatorTypeaheadDatasourceController' => 'PhabricatorController',
'PhabricatorUser' => 'PhabricatorUserDAO',
'PhabricatorUserDAO' => 'PhabricatorLiskDAO',
'PhabricatorUserOAuthInfo' => 'PhabricatorUserDAO',
'PhabricatorUserProfile' => 'PhabricatorUserDAO',
'PhabricatorUserSettingsController' => 'PhabricatorPeopleController',
'PhabricatorXHProfController' => 'PhabricatorController',
'PhabricatorXHProfProfileController' => 'PhabricatorXHProfController',
'PhabricatorXHProfProfileSymbolView' => 'AphrontView',
'PhabricatorXHProfProfileTopLevelView' => 'AphrontView',
),
'requires_interface' =>
array(
),
));
diff --git a/src/applications/differential/controller/attach/DifferentialAttachController.php b/src/applications/differential/controller/attach/DifferentialAttachController.php
index bfbebc48d5..c578c22098 100644
--- a/src/applications/differential/controller/attach/DifferentialAttachController.php
+++ b/src/applications/differential/controller/attach/DifferentialAttachController.php
@@ -1,117 +1,120 @@
<?php
/*
* Copyright 2011 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.
*/
class DifferentialAttachController extends DifferentialController {
private $id;
private $type;
public function willProcessRequest(array $data) {
$this->id = $data['id'];
$this->type = $data['type'];
}
public function processRequest() {
$request = $this->getRequest();
$user = $request->getUser();
$revision = id(new DifferentialRevision())->load($this->id);
if (!$revision) {
return new Aphront404Response();
}
if ($request->isFormPost()) {
$phids = explode(';', $request->getStr('phids'));
- $old_phids = $revision->getAttachedPHIDs('TASK');
+ $old_phids = $revision->getAttachedPHIDs(
+ PhabricatorPHIDConstants::PHID_TYPE_TASK);
if (($phids || $old_phids) && ($phids != $old_phids)) {
$tasks = id(new ManiphestTask())->loadAllWhere(
'phid in (%Ls)',
array_merge($phids, $old_phids));
$tasks = mpull($tasks, null, 'getPHID');
// Remove PHIDs which don't actually exist.
$phids = array_keys(array_select_keys($tasks, $phids));
$revision->setAttachedPHIDs($this->type, $phids);
$revision->save();
$editor = new ManiphestTransactionEditor();
$type = ManiphestTransactionType::TYPE_ATTACH;
foreach ($tasks as $task) {
$transaction = new ManiphestTransaction();
$transaction->setAuthorPHID($user->getPHID());
$transaction->setTransactionType($type);
$new = $task->getAttached();
- if (empty($new['DREV'])) {
- $new['DREV'] = array();
+ if (empty($new[PhabricatorPHIDConstants::PHID_TYPE_DREV])) {
+ $new[PhabricatorPHIDConstants::PHID_TYPE_DREV] = array();
}
$rev_phid = $revision->getPHID();
if (in_array($task->getPHID(), $phids)) {
- if (in_array($rev_phid, $task->getAttachedPHIDs('DREV'))) {
+ if (in_array($rev_phid, $task->getAttachedPHIDs(
+ PhabricatorPHIDConstants::PHID_TYPE_DREV))) {
// TODO: maybe the transaction editor should be responsible for
// this?
continue;
}
- $new['DREV'][$rev_phid] = array();
+ $new[PhabricatorPHIDConstants::PHID_TYPE_DREV][$rev_phid] = array();
} else {
- if (!in_array($rev_phid, $task->getAttachedPHIDs('DREV'))) {
+ if (!in_array($rev_phid, $task->getAttachedPHIDs(
+ PhabricatorPHIDConstants::PHID_TYPE_DREV))) {
continue;
}
- unset($new['DREV'][$rev_phid]);
+ unset($new[PhabricatorPHIDConstants::PHID_TYPE_DREV][$rev_phid]);
}
$transaction->setNewValue($new);
$editor->applyTransactions($task, array($transaction));
}
}
if ($request->isAjax()) {
return id(new AphrontRedirectResponse());
} else {
return id(new AphrontRedirectResponse())
->setURI('/D'.$revision->getID());
}
} else {
$phids = $revision->getAttachedPHIDs($this->type);
}
$handles = id(new PhabricatorObjectHandleData($phids))
->loadHandles();
$obj_dialog = new PhabricatorObjectSelectorDialog();
$obj_dialog
->setUser($user)
->setHandles($handles)
->setFilters(array(
'assigned' => 'Assigned to Me',
'created' => 'Created By Me',
'open' => 'All Open Tasks',
'all' => 'All Tasks',
))
->setCancelURI('#')
->setSearchURI('/maniphest/select/search/')
->setNoun('Tasks');
$dialog = $obj_dialog->buildDialog();
return id(new AphrontDialogResponse())->setDialog($dialog);
}
}
diff --git a/src/applications/differential/controller/attach/__init__.php b/src/applications/differential/controller/attach/__init__.php
index ec798503d2..ce807b085f 100644
--- a/src/applications/differential/controller/attach/__init__.php
+++ b/src/applications/differential/controller/attach/__init__.php
@@ -1,24 +1,25 @@
<?php
/**
* This file is automatically generated. Lint this module to rebuild it.
* @generated
*/
phutil_require_module('phabricator', 'aphront/response/404');
phutil_require_module('phabricator', 'aphront/response/dialog');
phutil_require_module('phabricator', 'aphront/response/redirect');
phutil_require_module('phabricator', 'applications/differential/controller/base');
phutil_require_module('phabricator', 'applications/differential/storage/revision');
phutil_require_module('phabricator', 'applications/maniphest/constants/transactiontype');
phutil_require_module('phabricator', 'applications/maniphest/editor/transaction');
phutil_require_module('phabricator', 'applications/maniphest/storage/task');
phutil_require_module('phabricator', 'applications/maniphest/storage/transaction');
+phutil_require_module('phabricator', 'applications/phid/constants');
phutil_require_module('phabricator', 'applications/phid/handle/data');
phutil_require_module('phabricator', 'view/control/objectselector');
phutil_require_module('phutil', 'utils');
phutil_require_source('DifferentialAttachController.php');
diff --git a/src/applications/differential/controller/revisionview/DifferentialRevisionViewController.php b/src/applications/differential/controller/revisionview/DifferentialRevisionViewController.php
index c08b5e0b31..94c3f7db00 100644
--- a/src/applications/differential/controller/revisionview/DifferentialRevisionViewController.php
+++ b/src/applications/differential/controller/revisionview/DifferentialRevisionViewController.php
@@ -1,723 +1,724 @@
<?php
/*
* Copyright 2011 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.
*/
class DifferentialRevisionViewController extends DifferentialController {
private $revisionID;
public function willProcessRequest(array $data) {
$this->revisionID = $data['id'];
}
public function processRequest() {
$request = $this->getRequest();
$user = $request->getUser();
$revision = id(new DifferentialRevision())->load($this->revisionID);
if (!$revision) {
return new Aphront404Response();
}
$revision->loadRelationships();
$diffs = $revision->loadDiffs();
$diff_vs = $request->getInt('vs');
$target = end($diffs);
$diffs = mpull($diffs, null, 'getID');
if (empty($diffs[$diff_vs])) {
$diff_vs = null;
}
list($changesets, $vs_map) =
$this->loadChangesetsAndVsMap($diffs, $diff_vs, $target);
$comments = $revision->loadComments();
$comments = array_merge(
$this->getImplicitComments($revision),
$comments);
$inlines = $this->loadInlineComments($comments, $changesets);
$object_phids = array_merge(
$revision->getReviewers(),
$revision->getCCPHIDs(),
array(
$revision->getAuthorPHID(),
$user->getPHID(),
),
mpull($comments, 'getAuthorPHID'));
foreach ($revision->getAttached() as $type => $phids) {
foreach ($phids as $phid => $info) {
$object_phids[] = $phid;
}
}
$object_phids = array_unique($object_phids);
$handles = id(new PhabricatorObjectHandleData($object_phids))
->loadHandles();
$request_uri = $request->getRequestURI();
$limit = 100;
$large = $request->getStr('large');
if (count($changesets) > $limit && !$large) {
$count = number_format(count($changesets));
$warning = new AphrontErrorView();
$warning->setTitle('Very Large Diff');
$warning->setSeverity(AphrontErrorView::SEVERITY_WARNING);
$warning->setWidth(AphrontErrorView::WIDTH_WIDE);
$warning->appendChild(
"<p>This diff is very large and affects {$count} files. Only ".
"the first {$limit} files are shown. ".
"<strong>".
phutil_render_tag(
'a',
array(
'href' => $request_uri->alter('large', 'true'),
),
'Show All Files').
"</strong>");
$warning = $warning->render();
$visible_changesets = array_slice($changesets, 0, $limit, true);
} else {
$warning = null;
$visible_changesets = $changesets;
}
$revision_detail = new DifferentialRevisionDetailView();
$revision_detail->setRevision($revision);
$properties = $this->getRevisionProperties($revision, $target, $handles);
$revision_detail->setProperties($properties);
$actions = $this->getRevisionActions($revision);
$revision_detail->setActions($actions);
$comment_view = new DifferentialRevisionCommentListView();
$comment_view->setComments($comments);
$comment_view->setHandles($handles);
$comment_view->setInlineComments($inlines);
$comment_view->setChangesets($changesets);
$comment_view->setUser($user);
$diff_history = new DifferentialRevisionUpdateHistoryView();
$diff_history->setDiffs($diffs);
$diff_history->setSelectedVersusDiffID($diff_vs);
$diff_history->setSelectedDiffID($target->getID());
$toc_view = new DifferentialDiffTableOfContentsView();
$toc_view->setChangesets($changesets);
$changeset_view = new DifferentialChangesetListView();
$changeset_view->setChangesets($visible_changesets);
$changeset_view->setEditable(true);
$changeset_view->setRevision($revision);
$changeset_view->setVsMap($vs_map);
$draft = id(new PhabricatorDraft())->loadOneWhere(
'authorPHID = %s AND draftKey = %s',
$user->getPHID(),
'differential-comment-'.$revision->getID());
if ($draft) {
$draft = $draft->getDraft();
} else {
$draft = null;
}
$comment_form = new DifferentialAddCommentView();
$comment_form->setRevision($revision);
$comment_form->setActions($this->getRevisionCommentActions($revision));
$comment_form->setActionURI('/differential/comment/save/');
$comment_form->setUser($user);
$comment_form->setDraft($draft);
return $this->buildStandardPageResponse(
'<div class="differential-primary-pane">'.
$revision_detail->render().
$comment_view->render().
$diff_history->render().
$toc_view->render().
$warning.
$changeset_view->render().
$comment_form->render().
'</div>',
array(
'title' => $revision->getTitle(),
));
}
private function getImplicitComments(DifferentialRevision $revision) {
$template = new DifferentialComment();
$template->setAuthorPHID($revision->getAuthorPHID());
$template->setRevisionID($revision->getID());
$template->setDateCreated($revision->getDateCreated());
$comments = array();
if (strlen($revision->getSummary())) {
$summary_comment = clone $template;
$summary_comment->setContent($revision->getSummary());
$summary_comment->setAction(DifferentialAction::ACTION_SUMMARIZE);
$comments[] = $summary_comment;
}
if (strlen($revision->getTestPlan())) {
$testplan_comment = clone $template;
$testplan_comment->setContent($revision->getTestPlan());
$testplan_comment->setAction(DifferentialAction::ACTION_TESTPLAN);
$comments[] = $testplan_comment;
}
return $comments;
}
private function getRevisionProperties(
DifferentialRevision $revision,
DifferentialDiff $diff,
array $handles) {
$properties = array();
$status = $revision->getStatus();
$status = DifferentialRevisionStatus::getNameForRevisionStatus($status);
$properties['Revision Status'] = '<strong>'.$status.'</strong>';
$author = $handles[$revision->getAuthorPHID()];
$properties['Author'] = $author->renderLink();
$properties['Reviewers'] = $this->renderHandleLinkList(
array_select_keys(
$handles,
$revision->getReviewers()));
$properties['CCs'] = $this->renderHandleLinkList(
array_select_keys(
$handles,
$revision->getCCPHIDs()));
$host = $diff->getSourceMachine();
if ($host) {
$properties['Host'] = phutil_escape_html($host);
}
$path = $diff->getSourcePath();
if ($path) {
$branch = $diff->getBranch() ? ' ('.$diff->getBranch().')' : '';
$properties['Path'] = phutil_escape_html("{$path} {$branch}");
}
$lstar = DifferentialRevisionUpdateHistoryView::renderDiffLintStar($diff);
$lmsg = DifferentialRevisionUpdateHistoryView::getDiffLintMessage($diff);
$properties['Lint'] = $lstar.' '.$lmsg;
$ustar = DifferentialRevisionUpdateHistoryView::renderDiffUnitStar($diff);
$umsg = DifferentialRevisionUpdateHistoryView::getDiffUnitMessage($diff);
$properties['Unit'] = $ustar.' '.$umsg;
- $tasks = $revision->getAttachedPHIDs('TASK');
+ $tasks = $revision->getAttachedPHIDs(
+ PhabricatorPHIDConstants::PHID_TYPE_TASK);
if ($tasks) {
$links = array();
foreach ($tasks as $task_phid) {
$links[] = $handles[$task_phid]->renderLink();
}
$properties['Maniphest Tasks'] = implode('<br />', $links);
}
return $properties;
}
private function getRevisionActions(DifferentialRevision $revision) {
$viewer_phid = $this->getRequest()->getUser()->getPHID();
$viewer_is_owner = ($revision->getAuthorPHID() == $viewer_phid);
$viewer_is_reviewer = in_array($viewer_phid, $revision->getReviewers());
$viewer_is_cc = in_array($viewer_phid, $revision->getCCPHIDs());
$status = $revision->getStatus();
$revision_id = $revision->getID();
$revision_phid = $revision->getPHID();
$links = array();
if ($viewer_is_owner) {
$links[] = array(
'class' => 'revision-edit',
'href' => "/differential/revision/edit/{$revision_id}/",
'name' => 'Edit Revision',
);
}
if (!$viewer_is_owner && !$viewer_is_reviewer) {
$action = $viewer_is_cc ? 'rem' : 'add';
$links[] = array(
'class' => $viewer_is_cc ? 'subscribe-rem' : 'subscribe-add',
'href' => "/differential/subscribe/{$action}/{$revision_id}/",
'name' => $viewer_is_cc ? 'Unsubscribe' : 'Subscribe',
'sigil' => 'workflow',
);
} else {
$links[] = array(
'class' => 'subscribe-rem unavailable',
'name' => 'Automatically Subscribed',
);
}
require_celerity_resource('phabricator-object-selector-css');
require_celerity_resource('javelin-behavior-phabricator-object-selector');
$links[] = array(
'class' => 'attach-maniphest',
'name' => 'Edit Maniphest Tasks',
'href' => "/differential/attach/{$revision_id}/TASK/",
'sigil' => 'workflow',
);
$links[] = array(
'class' => 'transcripts-metamta',
'name' => 'MetaMTA Transcripts',
'href' => "/mail/?phid={$revision_phid}",
);
return $links;
}
private function renderHandleLinkList(array $list) {
if (empty($list)) {
return '<em>None</em>';
}
return implode(', ', mpull($list, 'renderLink'));
}
private function getRevisionCommentActions(DifferentialRevision $revision) {
$actions = array(
DifferentialAction::ACTION_COMMENT => true,
);
$viewer_phid = $this->getRequest()->getUser()->getPHID();
$viewer_is_owner = ($viewer_phid == $revision->getAuthorPHID());
if ($viewer_is_owner) {
switch ($revision->getStatus()) {
case DifferentialRevisionStatus::NEEDS_REVIEW:
$actions[DifferentialAction::ACTION_ABANDON] = true;
break;
case DifferentialRevisionStatus::NEEDS_REVISION:
case DifferentialRevisionStatus::ACCEPTED:
$actions[DifferentialAction::ACTION_ABANDON] = true;
$actions[DifferentialAction::ACTION_REQUEST] = true;
break;
case DifferentialRevisionStatus::COMMITTED:
break;
case DifferentialRevisionStatus::ABANDONED:
$actions[DifferentialAction::ACTION_RECLAIM] = true;
break;
}
} else {
switch ($revision->getStatus()) {
case DifferentialRevisionStatus::NEEDS_REVIEW:
$actions[DifferentialAction::ACTION_ACCEPT] = true;
$actions[DifferentialAction::ACTION_REJECT] = true;
break;
case DifferentialRevisionStatus::NEEDS_REVISION:
$actions[DifferentialAction::ACTION_ACCEPT] = true;
break;
case DifferentialRevisionStatus::ACCEPTED:
$actions[DifferentialAction::ACTION_REJECT] = true;
break;
case DifferentialRevisionStatus::COMMITTED:
case DifferentialRevisionStatus::ABANDONED:
break;
}
}
$actions[DifferentialAction::ACTION_ADDREVIEWERS] = true;
return array_keys($actions);
}
private function loadInlineComments(array $comments, array &$changesets) {
$inline_comments = array();
$comment_ids = array_filter(mpull($comments, 'getID'));
if (!$comment_ids) {
return $inline_comments;
}
$inline_comments = id(new DifferentialInlineComment())
->loadAllWhere(
'commentID in (%Ld)',
$comment_ids);
$load_changesets = array();
foreach ($inline_comments as $inline) {
$changeset_id = $inline->getChangesetID();
if (isset($changesets[$changeset_id])) {
continue;
}
$load_changesets[$changeset_id] = true;
}
$more_changesets = array();
if ($load_changesets) {
$changeset_ids = array_keys($load_changesets);
$more_changesets += id(new DifferentialChangeset())
->loadAllWhere(
'id IN (%Ld)',
$changeset_ids);
}
if ($more_changesets) {
$changesets += $more_changesets;
$changesets = msort($changesets, 'getSortKey');
}
return $inline_comments;
}
private function loadChangesetsAndVsMap(array $diffs, $diff_vs, $target) {
$load_ids = array();
if ($diff_vs) {
$load_ids[] = $diff_vs;
}
$load_ids[] = $target->getID();
$raw_changesets = id(new DifferentialChangeset())
->loadAllWhere(
'diffID IN (%Ld)',
$load_ids);
$changeset_groups = mgroup($raw_changesets, 'getDiffID');
$changesets = idx($changeset_groups, $target->getID(), array());
$changesets = mpull($changesets, null, 'getID');
$vs_map = array();
if ($diff_vs) {
$vs_changesets = idx($changeset_groups, $diff_vs, array());
$vs_changesets = mpull($vs_changesets, null, 'getFilename');
foreach ($changesets as $key => $changeset) {
$file = $changeset->getFilename();
if (isset($vs_changesets[$file])) {
$vs_map[$changeset->getID()] = $vs_changesets[$file]->getID();
unset($vs_changesets[$file]);
}
}
foreach ($vs_changesets as $changeset) {
$changesets[$changeset->getID()] = $changeset;
$vs_map[$changeset->getID()] = -1;
}
}
$changesets = msort($changesets, 'getSortKey');
return array($changesets, $vs_map);
}
}
/*
protected function getSandcastleURI(Diff $diff) {
$uri = $this->getDiffProperty($diff, 'facebook:sandcastle_uri');
if (!$uri) {
$uri = $diff->getSandboxURL();
}
return $uri;
}
protected function getDiffProperty(Diff $diff, $property, $default = null) {
$diff_id = $diff->getID();
if (empty($this->diffProperties[$diff_id])) {
$props = id(new DifferentialDiffProperty())
->loadAllWhere('diffID = %s', $diff_id);
$dict = array_pull($props, 'getData', 'getName');
$this->diffProperties[$diff_id] = $dict;
}
return idx($this->diffProperties[$diff_id], $property, $default);
}
$diff_table->appendChild(
<tr>
<td colspan="8" class="diff-differ-submit">
<label>Whitespace Changes:</label>
{id(<select name="whitespace" />)->setOptions(
array(
'ignore-all' => 'Ignore All',
'ignore-trailing' => 'Ignore Trailing',
'show-all' => 'Show All',
), $request->getStr('whitespace'))}{' '}
<button type="submit">Show Diff</button>
</td>
</tr>);
$load_ids = array_filter(array($old, $diff->getID()));
$viewer_id = $this->getRequest()->getViewerContext()->getUserID();
$raw_objects = queryfx_all(
smc_get_db('cdb.differential', 'r'),
'SELECT * FROM changeset WHERE changeset.diffID IN (%Ld)',
$load_ids);
$raw_objects = array_group($raw_objects, 'diffID');
$objects = $raw_objects[$diff->getID()];
if (!$objects) {
$changesets = array();
} else {
$changesets = id(new DifferentialChangeset())->loadAllFromArray($objects);
}
$feedback = id(new DifferentialFeedback())->loadAllWithRevision($revision);
$feedback = array_merge($implied_feedback, $feedback);
$inline_comments = $this->loadInlineComments($feedback, $changesets);
$diff_map = array();
$diffs = array_psort($diffs, 'getID');
foreach ($diffs as $diff) {
$diff_map[$diff->getID()] = count($diff_map) + 1;
}
$visible_changesets = array_fill_keys($visible_changesets, true);
$hidden_changesets = array();
foreach ($changesets as $changeset) {
$id = $changeset->getID();
if (isset($visible_changesets[$id])) {
continue;
}
$hidden_changesets[$id] = $diff_map[$changeset->getDiffID()];
}
$engine = new RemarkupEngine();
$engine->enableFeature(RemarkupEngine::FEATURE_GUESS_IMAGES);
$engine->enableFeature(RemarkupEngine::FEATURE_YOUTUBE);
$engine->setCurrentSandcastle($this->getSandcastleURI($target_diff));
$syntax_link =
<a href={'http://www.intern.facebook.com/intern/wiki/index.php' .
'/Articles/Remarkup_Syntax_Reference'}
target="_blank"
tabindex="4">Remarkup Reference</a>;
$notice = null;
if ($this->getRequest()->getBool('diff_changed')) {
$notice =
<tools:notice title="Revision Updated Recently">
This revision was updated with a <strong>new diff</strong> while you
were providing feedback. Your inline comments appear on the
<strong>old diff</strong>.
</tools:notice>;
}
$blast_uri = RedirectURI(
'/intern/differential/?action=blast&fbid='.$revision->getFBID())
->setTier('intern');
$links[] = array(
'blast',
<a href={$blast_uri}>Blast Revision</a>,
);
$engineering_repository_id = RepositoryRef::getByCallsign('E')->getID();
$svn_revision = $revision->getSVNRevision();
if ($status == DifferentialConstants::COMMITTED &&
$svn_revision &&
$revision->getRepositoryID() == $engineering_repository_id) {
$href = '/intern/push/request.php?rev='.$svn_revision;
$href = RedirectURI($href)->setTier('intern');
$links[] = array(
'merge',
<a href={$href} id="ask_for_merge_link">Ask for Merge</a>,
);
}
$links[] = array(
'herald-transcript',
<a href={"/herald/transcript/?fbid=".$revision->getFBID()}
>Herald Transcripts</a>,
);
}
protected function renderDiffPropertyMoreLink(Diff $diff, $name) {
$target = <div class="star-more"
style="display: none;">
<div class="star-loading">Loading...</div>
</div>;
$meta = array(
'target' => $target->requireUniqueID(),
'uri' => '/differential/diffprop/'.$diff->getID().'/'.$name.'/',
);
$more =
<span sigil="star-link-container">
&middot;
<a mustcapture="true"
sigil="star-more"
href="#"
meta={$meta}>Show Details</a>
</span>;
return <x:frag>{$more}{$target}</x:frag>;
}
protected function getRevisionStatusDisplay(DifferentialRevision $revision) {
$viewer_id = $this->getRequest()->getViewerContext()->getUserID();
$viewer_is_owner = ($viewer_id == $revision->getOwnerID());
$status = $revision->getStatus();
$more = null;
switch ($status) {
case DifferentialConstants::NEEDS_REVIEW:
$message = 'Pending Review';
break;
case DifferentialConstants::NEEDS_REVISION:
$message = 'Awaiting Revision';
if ($viewer_is_owner) {
$more = 'Make the requested changes and update the revision.';
}
break;
case DifferentialConstants::ACCEPTED:
$message = 'Ready for Commit';
if ($viewer_is_owner) {
$more =
<x:frag>
Run <tt>arc commit</tt> (svn) or <tt>arc amend</tt> (git) to
proceed.
</x:frag>;
}
break;
case DifferentialConstants::COMMITTED:
$message = 'Committed';
$ref = $revision->getRevisionRef();
$more = $ref
? (<a href={URI($ref->getDetailURL())}>
{$ref->getName()}
</a>)
: null;
$engineering_repository_id = RepositoryRef::getByCallsign('E')->getID();
if ($revision->getSVNRevision() &&
$revision->getRepositoryID() == $engineering_repository_id) {
Javelin::initBehavior(
'differential-revtracker-status',
array(
'uri' => '/differential/revtracker/'.$revision->getID().'/',
'statusId' => 'revtracker_status',
'mergeLinkId' => 'ask_for_merge_link',
));
}
break;
case DifferentialConstants::ABANDONED:
$message = 'Abandoned';
break;
default:
throw new Exception("Unknown revision status.");
}
if ($more) {
$message =
<x:frag>
<strong id="revtracker_status">{$message}</strong>
&middot; {$more}
</x:frag>;
} else {
$message = <strong id="revtracker_status">{$message}</strong>;
}
return $message;
}
}
protected function getDetailFields(
DifferentialRevision $revision,
Diff $diff,
array $handles) {
$sandcastle = $this->getSandcastleURI($diff);
if ($sandcastle) {
$fields['Sandcastle'] = <a href={$sandcastle}>{$sandcastle}</a>;
}
$blame_rev = $revision->getSvnBlameRevision();
if ($blame_rev) {
if ($revision->getRepositoryRef() && is_numeric($blame_rev)) {
$ref = new RevisionRef($revision->getRepositoryRef(), $blame_rev);
$fields['Blame Revision'] =
<a href={URI($ref->getDetailURL())}>
{$ref->getName()}
</a>;
} else {
$fields['Blame Revision'] = $blame_rev;
}
}
$bugzilla_id = $revision->getBugzillaID();
if ($bugzilla_id) {
$href = 'http://bugs.developers.facebook.com/show_bug.cgi?id='.
$bugzilla_id;
$fields['Bugzilla'] = <a href={$href}>{'#'.$bugzilla_id}</a>;
}
$fields['Apply Patch'] = <tt>arc patch --revision {$revision->getID()}</tt>;
if ($diff->getParentRevisionID()) {
$parent = id(new DifferentialRevision())->load(
$diff->getParentRevisionID());
if ($parent) {
$fields['Depends On'] =
<a href={$parent->getURI()}>
D{$parent->getID()}: {$parent->getName()}
</a>;
}
}
Javelin::initBehavior('differential-star-more');
if ($unit_details) {
$fields['Unit Tests'] =
<x:frag>
{$fields['Unit Tests']}
{$this->renderDiffPropertyMoreLink($diff, 'unit')}
</x:frag>;
}
$platform_impact = $revision->getPlatformImpact();
if ($platform_impact) {
$fields['Platform Impact'] =
<text linebreaks="true">{$platform_impact}</text>;
}
return $fields;
}
*/
diff --git a/src/applications/differential/controller/revisionview/__init__.php b/src/applications/differential/controller/revisionview/__init__.php
index 64e62cc7c6..c6e009de3c 100644
--- a/src/applications/differential/controller/revisionview/__init__.php
+++ b/src/applications/differential/controller/revisionview/__init__.php
@@ -1,32 +1,33 @@
<?php
/**
* This file is automatically generated. Lint this module to rebuild it.
* @generated
*/
phutil_require_module('phabricator', 'aphront/response/404');
phutil_require_module('phabricator', 'applications/differential/constants/action');
phutil_require_module('phabricator', 'applications/differential/constants/revisionstatus');
phutil_require_module('phabricator', 'applications/differential/controller/base');
phutil_require_module('phabricator', 'applications/differential/storage/changeset');
phutil_require_module('phabricator', 'applications/differential/storage/comment');
phutil_require_module('phabricator', 'applications/differential/storage/inlinecomment');
phutil_require_module('phabricator', 'applications/differential/storage/revision');
phutil_require_module('phabricator', 'applications/differential/view/addcomment');
phutil_require_module('phabricator', 'applications/differential/view/changesetlistview');
phutil_require_module('phabricator', 'applications/differential/view/difftableofcontents');
phutil_require_module('phabricator', 'applications/differential/view/revisioncommentlist');
phutil_require_module('phabricator', 'applications/differential/view/revisiondetail');
phutil_require_module('phabricator', 'applications/differential/view/revisionupdatehistory');
phutil_require_module('phabricator', 'applications/draft/storage/draft');
+phutil_require_module('phabricator', 'applications/phid/constants');
phutil_require_module('phabricator', 'applications/phid/handle/data');
phutil_require_module('phabricator', 'infrastructure/celerity/api');
phutil_require_module('phabricator', 'view/form/error');
phutil_require_module('phutil', 'markup');
phutil_require_module('phutil', 'utils');
phutil_require_source('DifferentialRevisionViewController.php');
diff --git a/src/applications/differential/storage/revision/DifferentialRevision.php b/src/applications/differential/storage/revision/DifferentialRevision.php
index a99c16ec59..047929ebd5 100755
--- a/src/applications/differential/storage/revision/DifferentialRevision.php
+++ b/src/applications/differential/storage/revision/DifferentialRevision.php
@@ -1,128 +1,129 @@
<?php
/*
* Copyright 2011 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.
*/
class DifferentialRevision extends DifferentialDAO {
protected $title;
protected $status;
protected $summary;
protected $testPlan;
protected $revertPlan;
protected $blameRevision;
protected $phid;
protected $authorPHID;
protected $dateCommitted;
protected $lineCount;
protected $attached = array();
protected $unsubscribed = array();
private $relationships;
const RELATIONSHIP_TABLE = 'differential_relationship';
const RELATION_REVIEWER = 'revw';
const RELATION_SUBSCRIBED = 'subd';
public function getConfiguration() {
return array(
self::CONFIG_AUX_PHID => true,
self::CONFIG_SERIALIZATION => array(
'attached' => self::SERIALIZATION_JSON,
'unsubscribed' => self::SERIALIZATION_JSON,
),
) + parent::getConfiguration();
}
public function getAttachedPHIDs($type) {
return array_keys(idx($this->attached, $type, array()));
}
public function setAttachedPHIDs($type, array $phids) {
$this->attached[$type] = array_fill_keys($phids, array());
return $this;
}
public function generatePHID() {
- return PhabricatorPHID::generateNewPHID('DREV');
+ return PhabricatorPHID::generateNewPHID(
+ PhabricatorPHIDConstants::PHID_TYPE_DREV);
}
public function loadDiffs() {
if (!$this->getID()) {
return array();
}
return id(new DifferentialDiff())->loadAllWhere(
'revisionID = %d',
$this->getID());
}
public function loadComments() {
if (!$this->getID()) {
return array();
}
return id(new DifferentialComment())->loadAllWhere(
'revisionID = %d',
$this->getID());
}
public function loadActiveDiff() {
return id(new DifferentialDiff())->loadOneWhere(
'revisionID = %d ORDER BY id DESC LIMIT 1',
$this->getID());
}
public function loadRelationships() {
if (!$this->getID()) {
$this->relationships = array();
return;
}
$data = queryfx_all(
$this->establishConnection('r'),
'SELECT * FROM %T WHERE revisionID = %d ORDER BY sequence',
self::RELATIONSHIP_TABLE,
$this->getID());
$this->relationships = igroup($data, 'relation');
return $this;
}
public function getReviewers() {
return $this->getRelatedPHIDs(self::RELATION_REVIEWER);
}
public function getCCPHIDs() {
return $this->getRelatedPHIDs(self::RELATION_SUBSCRIBED);
}
private function getRelatedPHIDs($relation) {
if ($this->relationships === null) {
throw new Exception("Must load relationships!");
}
return ipull($this->getRawRelations($relation), 'objectPHID');
}
public function getRawRelations($relation) {
return idx($this->relationships, $relation, array());
}
}
diff --git a/src/applications/differential/storage/revision/__init__.php b/src/applications/differential/storage/revision/__init__.php
index 3720822856..a6690c2650 100644
--- a/src/applications/differential/storage/revision/__init__.php
+++ b/src/applications/differential/storage/revision/__init__.php
@@ -1,18 +1,19 @@
<?php
/**
* This file is automatically generated. Lint this module to rebuild it.
* @generated
*/
phutil_require_module('phabricator', 'applications/differential/storage/base');
phutil_require_module('phabricator', 'applications/differential/storage/comment');
phutil_require_module('phabricator', 'applications/differential/storage/diff');
+phutil_require_module('phabricator', 'applications/phid/constants');
phutil_require_module('phabricator', 'applications/phid/storage/phid');
phutil_require_module('phabricator', 'storage/queryfx');
phutil_require_module('phutil', 'utils');
phutil_require_source('DifferentialRevision.php');
diff --git a/src/applications/files/storage/file/PhabricatorFile.php b/src/applications/files/storage/file/PhabricatorFile.php
index 84a7d19a63..4a900cdb0f 100644
--- a/src/applications/files/storage/file/PhabricatorFile.php
+++ b/src/applications/files/storage/file/PhabricatorFile.php
@@ -1,192 +1,191 @@
<?php
/*
* Copyright 2011 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.
*/
class PhabricatorFile extends PhabricatorFileDAO {
const STORAGE_ENGINE_BLOB = 'blob';
const STORAGE_FORMAT_RAW = 'raw';
- const PHID_TYPE = 'FILE';
-
// TODO: We need to reconcile this with MySQL packet size.
const FILE_SIZE_BYTE_LIMIT = 12582912;
protected $phid;
protected $name;
protected $mimeType;
protected $byteSize;
protected $storageEngine;
protected $storageFormat;
protected $storageHandle;
public function getConfiguration() {
return array(
self::CONFIG_AUX_PHID => true,
) + parent::getConfiguration();
}
public function generatePHID() {
- return PhabricatorPHID::generateNewPHID(self::PHID_TYPE);
+ return PhabricatorPHID::generateNewPHID(
+ PhabricatorPHIDConstants::PHID_TYPE_FILE);
}
public static function newFromPHPUpload($spec, array $params = array()) {
if (!$spec) {
throw new Exception("No file was uploaded!");
}
$err = idx($spec, 'error');
if ($err) {
throw new Exception("File upload failed with error '{$err}'.");
}
$tmp_name = idx($spec, 'tmp_name');
$is_valid = @is_uploaded_file($tmp_name);
if (!$is_valid) {
throw new Exception("File is not an uploaded file.");
}
$file_data = Filesystem::readFile($tmp_name);
$file_size = idx($spec, 'size');
if (strlen($file_data) != $file_size) {
throw new Exception("File size disagrees with uploaded size.");
}
$file_name = nonempty(
idx($params, 'name'),
idx($spec, 'name'));
$params = array(
'name' => $file_name,
) + $params;
return self::newFromFileData($file_data, $params);
}
public static function newFromFileData($data, array $params = array()) {
$file_size = strlen($data);
if ($file_size > self::FILE_SIZE_BYTE_LIMIT) {
throw new Exception("File is too large to store.");
}
$file_name = idx($params, 'name');
$file_name = self::normalizeFileName($file_name);
$file = new PhabricatorFile();
$file->setName($file_name);
$file->setByteSize(strlen($data));
$blob = new PhabricatorFileStorageBlob();
$blob->setData($data);
$blob->save();
// TODO: This stuff is almost certainly YAGNI, but we could imagine having
// an alternate disk store and gzipping or encrypting things or something
// crazy like that and this isn't toooo much extra code.
$file->setStorageEngine(self::STORAGE_ENGINE_BLOB);
$file->setStorageFormat(self::STORAGE_FORMAT_RAW);
$file->setStorageHandle($blob->getID());
if (isset($params['mime-type'])) {
$file->setMimeType($params['mime-type']);
} else {
try {
$tmp = new TempFile();
Filesystem::writeFile($tmp, $data);
list($stdout) = execx('file -b --mime %s', $tmp);
$file->setMimeType($stdout);
} catch (Exception $ex) {
// Be robust here since we don't really care that much about mime types.
}
}
$file->save();
return $file;
}
public static function normalizeFileName($file_name) {
return preg_replace('/[^a-zA-Z0-9.~_-]/', '_', $file_name);
}
public function delete() {
$this->openTransaction();
switch ($this->getStorageEngine()) {
case self::STORAGE_ENGINE_BLOB:
$handle = $this->getStorageHandle();
$blob = id(new PhabricatorFileStorageBlob())->load($handle);
$blob->delete();
break;
default:
throw new Exception("Unknown storage engine!");
}
$ret = parent::delete();
$this->saveTransaction();
return $ret;
}
public function loadFileData() {
$handle = $this->getStorageHandle();
$data = null;
switch ($this->getStorageEngine()) {
case self::STORAGE_ENGINE_BLOB:
$blob = id(new PhabricatorFileStorageBlob())->load($handle);
if (!$blob) {
throw new Exception("Failed to load file blob data.");
}
$data = $blob->getData();
break;
default:
throw new Exception("Unknown storage engine.");
}
switch ($this->getStorageFormat()) {
case self::STORAGE_FORMAT_RAW:
$data = $data;
break;
default:
throw new Exception("Unknown storage format.");
}
return $data;
}
public function getViewURI() {
return PhabricatorFileURI::getViewURIForPHID($this->getPHID());
}
public function isViewableInBrowser() {
return ($this->getViewableMimeType() !== null);
}
public function getViewableMimeType() {
$mime_map = PhabricatorEnv::getEnvConfig('files.viewable-mime-types');
$mime_type = $this->getMimeType();
$mime_parts = explode(';', $mime_type);
$mime_type = trim(reset($mime_parts));
return idx($mime_map, $mime_type);
}
}
diff --git a/src/applications/files/storage/file/__init__.php b/src/applications/files/storage/file/__init__.php
index b15ce974a2..1c82529ee4 100644
--- a/src/applications/files/storage/file/__init__.php
+++ b/src/applications/files/storage/file/__init__.php
@@ -1,21 +1,22 @@
<?php
/**
* This file is automatically generated. Lint this module to rebuild it.
* @generated
*/
phutil_require_module('phabricator', 'applications/files/storage/base');
phutil_require_module('phabricator', 'applications/files/storage/storageblob');
phutil_require_module('phabricator', 'applications/files/uri');
+phutil_require_module('phabricator', 'applications/phid/constants');
phutil_require_module('phabricator', 'applications/phid/storage/phid');
phutil_require_module('phabricator', 'infrastructure/env');
phutil_require_module('phutil', 'filesystem');
phutil_require_module('phutil', 'filesystem/tempfile');
phutil_require_module('phutil', 'future/exec');
phutil_require_module('phutil', 'utils');
phutil_require_source('PhabricatorFile.php');
diff --git a/src/applications/maniphest/controller/taskdetail/ManiphestTaskDetailController.php b/src/applications/maniphest/controller/taskdetail/ManiphestTaskDetailController.php
index cf32bfc45c..144d4589f6 100644
--- a/src/applications/maniphest/controller/taskdetail/ManiphestTaskDetailController.php
+++ b/src/applications/maniphest/controller/taskdetail/ManiphestTaskDetailController.php
@@ -1,322 +1,322 @@
<?php
/*
* Copyright 2011 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.
*/
class ManiphestTaskDetailController extends ManiphestController {
private $id;
public function willProcessRequest(array $data) {
$this->id = $data['id'];
}
public function processRequest() {
$request = $this->getRequest();
$user = $request->getUser();
$e_title = null;
$priority_map = ManiphestTaskPriority::getTaskPriorityMap();
$task = id(new ManiphestTask())->load($this->id);
$transactions = id(new ManiphestTransaction())->loadAllWhere(
'taskID = %d',
$task->getID());
$phids = array();
foreach ($transactions as $transaction) {
foreach ($transaction->extractPHIDs() as $phid) {
$phids[$phid] = true;
}
}
foreach ($task->getCCPHIDs() as $phid) {
$phids[$phid] = true;
}
foreach ($task->getProjectPHIDs() as $phid) {
$phids[$phid] = true;
}
if ($task->getOwnerPHID()) {
$phids[$task->getOwnerPHID()] = true;
}
$phids[$task->getAuthorPHID()] = true;
$phids = array_keys($phids);
$attached = $task->getAttached();
foreach ($attached as $type => $list) {
foreach ($list as $phid => $info) {
$phids[$phid] = true;
}
}
$handles = id(new PhabricatorObjectHandleData($phids))
->loadHandles();
$factory = new DifferentialMarkupEngineFactory();
$engine = $factory->newDifferentialCommentMarkupEngine();
$dict = array();
$dict['Status'] =
'<strong>'.
ManiphestTaskStatus::getTaskStatusFullName($task->getStatus()).
'</strong>';
$dict['Assigned To'] = $task->getOwnerPHID()
? $handles[$task->getOwnerPHID()]->renderLink()
: '<em>None</em>';
$dict['Priority'] = ManiphestTaskPriority::getTaskPriorityName(
$task->getPriority());
$cc = $task->getCCPHIDs();
if ($cc) {
$cc_links = array();
foreach ($cc as $phid) {
$cc_links[] = $handles[$phid]->renderLink();
}
$dict['CC'] = implode(', ', $cc_links);
} else {
$dict['CC'] = '<em>None</em>';
}
$dict['Author'] = $handles[$task->getAuthorPHID()]->renderLink();
$projects = $task->getProjectPHIDs();
if ($projects) {
$project_links = array();
foreach ($projects as $phid) {
$project_links[] = $handles[$phid]->renderLink();
}
$dict['Projects'] = implode(', ', $project_links);
} else {
$dict['Projects'] = '<em>None</em>';
}
- if (idx($attached, 'DREV')) {
- $revs = idx($attached, 'DREV');
+ if (idx($attached, PhabricatorPHIDConstants::PHID_TYPE_DREV)) {
+ $revs = idx($attached, PhabricatorPHIDConstants::PHID_TYPE_DREV);
$rev_links = array();
foreach ($revs as $rev => $info) {
$rev_links[] = $handles[$rev]->renderLink();
}
$rev_links = implode(', ', $rev_links);
$dict['Revisions'] = $rev_links;
}
- if (idx($attached, 'FILE')) {
- $revs = idx($attached, 'FILE');
+ if (idx($attached, PhabricatorPHIDConstants::PHID_TYPE_FILE)) {
+ $revs = idx($attached, PhabricatorPHIDConstants::PHID_TYPE_FILE);
$rev_links = array();
foreach ($revs as $rev => $info) {
$rev_links[] = $handles[$rev]->renderLink();
}
$rev_links = implode(', ', $rev_links);
$dict['Files'] = $rev_links;
}
$dict['Description'] =
'<div class="maniphest-task-description">'.
'<div class="phabricator-remarkup">'.
$engine->markupText($task->getDescription()).
'</div>'.
'</div>';
require_celerity_resource('mainphest-task-detail-css');
$table = array();
foreach ($dict as $key => $value) {
$table[] =
'<tr>'.
'<th>'.phutil_escape_html($key).':</th>'.
'<td>'.$value.'</td>'.
'</tr>';
}
$table =
'<table class="maniphest-task-properties">'.
implode("\n", $table).
'</table>';
$actions = array();
$action = new AphrontHeadsupActionView();
$action->setName('Edit Task');
$action->setURI('/maniphest/task/edit/'.$task->getID().'/');
$action->setClass('action-edit');
$actions[] = $action;
$action = new AphrontHeadsupActionView();
$action->setName('Edit Differential Revisions');
$action->setClass('action-attach unavailable');
$actions[] = $action;
$action_list = new AphrontHeadsupActionListView();
$action_list->setActions($actions);
$panel =
'<div class="maniphest-panel">'.
$action_list->render().
'<div class="maniphest-task-detail-core">'.
'<h1>'.
phutil_escape_html('T'.$task->getID().' '.$task->getTitle()).
'</h1>'.
$table.
'</div>'.
'</div>';
$transaction_types = ManiphestTransactionType::getTransactionTypeMap();
$resolution_types = ManiphestTaskStatus::getTaskStatusMap();
if ($task->getStatus() == ManiphestTaskStatus::STATUS_OPEN) {
$resolution_types = array_select_keys(
$resolution_types,
array(
ManiphestTaskStatus::STATUS_CLOSED_RESOLVED,
ManiphestTaskStatus::STATUS_CLOSED_WONTFIX,
ManiphestTaskStatus::STATUS_CLOSED_INVALID,
ManiphestTaskStatus::STATUS_CLOSED_SPITE,
));
} else {
$resolution_types = array(
ManiphestTaskStatus::STATUS_OPEN => 'Reopened',
);
$transaction_types[ManiphestTransactionType::TYPE_STATUS] =
'Reopen Task';
unset($transaction_types[ManiphestTransactionType::TYPE_PRIORITY]);
unset($transaction_types[ManiphestTransactionType::TYPE_OWNER]);
}
$default_claim = array(
$user->getPHID() => $user->getUsername().' ('.$user->getRealName().')',
);
$comment_form = new AphrontFormView();
$comment_form
->setUser($user)
->setAction('/maniphest/transaction/save/')
->setEncType('multipart/form-data')
->addHiddenInput('taskID', $task->getID())
->appendChild(
id(new AphrontFormSelectControl())
->setLabel('Action')
->setName('action')
->setOptions($transaction_types)
->setID('transaction-action'))
->appendChild(
id(new AphrontFormSelectControl())
->setLabel('Resolution')
->setName('resolution')
->setControlID('resolution')
->setControlStyle('display: none')
->setOptions($resolution_types))
->appendChild(
id(new AphrontFormTokenizerControl())
->setLabel('Assign To')
->setName('assign_to')
->setControlID('assign_to')
->setControlStyle('display: none')
->setID('assign-tokenizer')
->setDisableBehavior(true))
->appendChild(
id(new AphrontFormTokenizerControl())
->setLabel('CCs')
->setName('ccs')
->setControlID('ccs')
->setControlStyle('display: none')
->setID('cc-tokenizer')
->setDisableBehavior(true))
->appendChild(
id(new AphrontFormSelectControl())
->setLabel('Priority')
->setName('priority')
->setOptions($priority_map)
->setControlID('priority')
->setControlStyle('display: none')
->setValue($task->getPriority()))
->appendChild(
id(new AphrontFormTokenizerControl())
->setLabel('Projects')
->setName('projects')
->setControlID('projects')
->setControlStyle('display: none')
->setID('projects-tokenizer')
->setDisableBehavior(true))
->appendChild(
id(new AphrontFormFileControl())
->setLabel('File')
->setName('file')
->setControlID('file')
->setControlStyle('display: none'))
->appendChild(
id(new AphrontFormTextAreaControl())
->setLabel('Comments')
->setName('comments')
->setValue(''))
->appendChild(
id(new AphrontFormSubmitControl())
->setValue('Avast!'));
Javelin::initBehavior('maniphest-transaction-controls', array(
'select' => 'transaction-action',
'controlMap' => array(
ManiphestTransactionType::TYPE_STATUS => 'resolution',
ManiphestTransactionType::TYPE_OWNER => 'assign_to',
ManiphestTransactionType::TYPE_CCS => 'ccs',
ManiphestTransactionType::TYPE_PRIORITY => 'priority',
ManiphestTransactionType::TYPE_PROJECTS => 'projects',
ManiphestTransactionType::TYPE_ATTACH => 'file',
),
'tokenizers' => array(
ManiphestTransactionType::TYPE_PROJECTS => array(
'id' => 'projects-tokenizer',
'src' => '/typeahead/common/projects/',
),
ManiphestTransactionType::TYPE_OWNER => array(
'id' => 'assign-tokenizer',
'src' => '/typeahead/common/users/',
'value' => $default_claim,
'limit' => 1,
),
ManiphestTransactionType::TYPE_CCS => array(
'id' => 'cc-tokenizer',
'src' => '/typeahead/common/mailable/',
),
),
));
$comment_panel = new AphrontPanelView();
$comment_panel->appendChild($comment_form);
$comment_panel->setHeader('Leap Into Action');
$transaction_view = new ManiphestTransactionListView();
$transaction_view->setTransactions($transactions);
$transaction_view->setHandles($handles);
$transaction_view->setUser($user);
$transaction_view->setMarkupEngine($engine);
return $this->buildStandardPageResponse(
array(
$panel,
$transaction_view,
$comment_panel,
),
array(
'title' => 'T'.$task->getID().' '.$task->getTitle(),
));
}
}
diff --git a/src/applications/maniphest/controller/taskdetail/__init__.php b/src/applications/maniphest/controller/taskdetail/__init__.php
index 893586896a..c711ba21b9 100644
--- a/src/applications/maniphest/controller/taskdetail/__init__.php
+++ b/src/applications/maniphest/controller/taskdetail/__init__.php
@@ -1,30 +1,31 @@
<?php
/**
* This file is automatically generated. Lint this module to rebuild it.
* @generated
*/
phutil_require_module('phabricator', 'applications/differential/parser/markup');
phutil_require_module('phabricator', 'applications/maniphest/constants/priority');
phutil_require_module('phabricator', 'applications/maniphest/constants/status');
phutil_require_module('phabricator', 'applications/maniphest/constants/transactiontype');
phutil_require_module('phabricator', 'applications/maniphest/controller/base');
phutil_require_module('phabricator', 'applications/maniphest/storage/task');
phutil_require_module('phabricator', 'applications/maniphest/storage/transaction');
phutil_require_module('phabricator', 'applications/maniphest/view/transactionlist');
+phutil_require_module('phabricator', 'applications/phid/constants');
phutil_require_module('phabricator', 'applications/phid/handle/data');
phutil_require_module('phabricator', 'infrastructure/celerity/api');
phutil_require_module('phabricator', 'infrastructure/javelin/api');
phutil_require_module('phabricator', 'view/form/base');
phutil_require_module('phabricator', 'view/form/control/submit');
phutil_require_module('phabricator', 'view/layout/headsup/action');
phutil_require_module('phabricator', 'view/layout/headsup/actionlist');
phutil_require_module('phabricator', 'view/layout/panel');
phutil_require_module('phutil', 'markup');
phutil_require_module('phutil', 'utils');
phutil_require_source('ManiphestTaskDetailController.php');
diff --git a/src/applications/maniphest/controller/taskselectorsearch/ManiphestTaskSelectorSearchController.php b/src/applications/maniphest/controller/taskselectorsearch/ManiphestTaskSelectorSearchController.php
index 14a591969a..f547f5e592 100644
--- a/src/applications/maniphest/controller/taskselectorsearch/ManiphestTaskSelectorSearchController.php
+++ b/src/applications/maniphest/controller/taskselectorsearch/ManiphestTaskSelectorSearchController.php
@@ -1,58 +1,58 @@
<?php
/*
* Copyright 2011 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.
*/
class ManiphestTaskSelectorSearchController extends ManiphestController {
public function processRequest() {
$request = $this->getRequest();
$user = $request->getUser();
$query = new PhabricatorSearchQuery();
$query->setQuery($request->getStr('query'));
- $query->setParameter('type', 'TASK');
+ $query->setParameter('type', PhabricatorPHIDConstants::PHID_TYPE_TASK);
switch ($request->getStr('filter')) {
case 'assigned':
$query->setParameter('owner', array($user->getPHID()));
$query->setParameter('open', 1);
break;
case 'created';
$query->setParameter('author', array($user->getPHID()));
$query->setParameter('open', 1);
break;
case 'open':
$query->setParameter('open', 1);
break;
}
$exec = new PhabricatorSearchMySQLExecutor();
$results = $exec->executeSearch($query);
$results = ipull($results, 'phid');
$handles = id(new PhabricatorObjectHandleData($results))
->loadHandles();
$data = array();
foreach ($handles as $handle) {
$view = new PhabricatorHandleObjectSelectorDataView($handle);
$data[] = $view->renderData();
}
return id(new AphrontAjaxResponse())->setContent($data);
}
}
diff --git a/src/applications/maniphest/controller/taskselectorsearch/__init__.php b/src/applications/maniphest/controller/taskselectorsearch/__init__.php
index 63b05f488d..3475c1e17b 100644
--- a/src/applications/maniphest/controller/taskselectorsearch/__init__.php
+++ b/src/applications/maniphest/controller/taskselectorsearch/__init__.php
@@ -1,19 +1,20 @@
<?php
/**
* This file is automatically generated. Lint this module to rebuild it.
* @generated
*/
phutil_require_module('phabricator', 'aphront/response/ajax');
phutil_require_module('phabricator', 'applications/maniphest/controller/base');
+phutil_require_module('phabricator', 'applications/phid/constants');
phutil_require_module('phabricator', 'applications/phid/handle/data');
phutil_require_module('phabricator', 'applications/phid/handle/view/selector');
phutil_require_module('phabricator', 'applications/search/execute/mysql');
phutil_require_module('phabricator', 'applications/search/storage/query');
phutil_require_module('phutil', 'utils');
phutil_require_source('ManiphestTaskSelectorSearchController.php');
diff --git a/src/applications/maniphest/controller/transactionsave/ManiphestTransactionSaveController.php b/src/applications/maniphest/controller/transactionsave/ManiphestTransactionSaveController.php
index 09adbe32de..07762ee649 100644
--- a/src/applications/maniphest/controller/transactionsave/ManiphestTransactionSaveController.php
+++ b/src/applications/maniphest/controller/transactionsave/ManiphestTransactionSaveController.php
@@ -1,122 +1,122 @@
<?php
/*
* Copyright 2011 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.
*/
class ManiphestTransactionSaveController extends ManiphestController {
public function processRequest() {
$request = $this->getRequest();
$user = $request->getUser();
$task = id(new ManiphestTask())->load($request->getStr('taskID'));
if (!$task) {
return new Aphront404Response();
}
$action = $request->getStr('action');
$transaction = new ManiphestTransaction();
$transaction
->setAuthorPHID($user->getPHID())
->setComments($request->getStr('comments'))
->setTransactionType($action);
switch ($action) {
case ManiphestTransactionType::TYPE_NONE:
break;
case ManiphestTransactionType::TYPE_STATUS:
$transaction->setNewValue($request->getStr('resolution'));
break;
case ManiphestTransactionType::TYPE_OWNER:
$assign_to = $request->getArr('assign_to');
$assign_to = reset($assign_to);
$transaction->setNewValue($assign_to);
break;
case ManiphestTransactionType::TYPE_PROJECTS:
$projects = $request->getArr('projects');
$projects = array_merge($projects, $task->getProjectPHIDs());
$projects = array_filter($projects);
$projects = array_unique($projects);
$transaction->setNewValue($projects);
break;
case ManiphestTransactionType::TYPE_CCS:
$ccs = $request->getArr('ccs');
$ccs = array_merge($ccs, $task->getCCPHIDs());
$ccs = array_filter($ccs);
$ccs = array_unique($ccs);
$transaction->setNewValue($ccs);
break;
case ManiphestTransactionType::TYPE_PRIORITY:
$transaction->setNewValue($request->getInt('priority'));
break;
case ManiphestTransactionType::TYPE_ATTACH:
// This means "attach a file" even though we store other types of data
// as 'attached'.
$phid = null;
if (!empty($_FILES['file'])) {
$err = idx($_FILES['file'], 'error');
if ($err != UPLOAD_ERR_NO_FILE) {
$file = PhabricatorFile::newFromPHPUpload($_FILES['file']);
$phid = $file->getPHID();
}
}
if ($phid) {
$new = $task->getAttached();
- if (empty($new['FILE'])) {
- $new['FILE'] = array();
+ if (empty($new[PhabricatorPHIDConstants::PHID_TYPE_FILE])) {
+ $new[PhabricatorPHIDConstants::PHID_TYPE_FILE] = array();
}
- $new['FILE'][$phid] = array();
+ $new[PhabricatorPHIDConstants::PHID_TYPE_FILE][$phid] = array();
}
$transaction->setNewValue($new);
break;
default:
throw new Exception('unknown action');
}
$transactions = array($transaction);
switch ($action) {
case ManiphestTransactionType::TYPE_OWNER:
if ($task->getOwnerPHID() == $transaction->getNewValue()) {
// If this is actually no-op, don't generate the side effect.
break;
}
// When a task is reassigned, move the previous owner to CC.
$old = $task->getCCPHIDs();
$new = array_merge(
$old,
array($task->getOwnerPHID()));
$new = array_unique(array_filter($new));
if ($old != $new) {
$cc = new ManiphestTransaction();
$cc->setAuthorPHID($user->getPHID());
$cc->setTransactionType(ManiphestTransactionType::TYPE_CCS);
$cc->setNewValue($new);
$transactions[] = $cc;
}
break;
}
$editor = new ManiphestTransactionEditor();
$editor->applyTransactions($task, $transactions);
return id(new AphrontRedirectResponse())
->setURI('/T'.$task->getID());
}
}
diff --git a/src/applications/maniphest/controller/transactionsave/__init__.php b/src/applications/maniphest/controller/transactionsave/__init__.php
index d2a6f38e6d..b7e5685a08 100644
--- a/src/applications/maniphest/controller/transactionsave/__init__.php
+++ b/src/applications/maniphest/controller/transactionsave/__init__.php
@@ -1,21 +1,22 @@
<?php
/**
* This file is automatically generated. Lint this module to rebuild it.
* @generated
*/
phutil_require_module('phabricator', 'aphront/response/404');
phutil_require_module('phabricator', 'aphront/response/redirect');
phutil_require_module('phabricator', 'applications/files/storage/file');
phutil_require_module('phabricator', 'applications/maniphest/constants/transactiontype');
phutil_require_module('phabricator', 'applications/maniphest/controller/base');
phutil_require_module('phabricator', 'applications/maniphest/editor/transaction');
phutil_require_module('phabricator', 'applications/maniphest/storage/task');
phutil_require_module('phabricator', 'applications/maniphest/storage/transaction');
+phutil_require_module('phabricator', 'applications/phid/constants');
phutil_require_module('phutil', 'utils');
phutil_require_source('ManiphestTransactionSaveController.php');
diff --git a/src/applications/maniphest/storage/task/ManiphestTask.php b/src/applications/maniphest/storage/task/ManiphestTask.php
index 9bf1bb328e..8c8f692429 100644
--- a/src/applications/maniphest/storage/task/ManiphestTask.php
+++ b/src/applications/maniphest/storage/task/ManiphestTask.php
@@ -1,58 +1,59 @@
<?php
/*
* Copyright 2011 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.
*/
class ManiphestTask extends ManiphestDAO {
protected $phid;
protected $authorPHID;
protected $ownerPHID;
protected $ccPHIDs = array();
protected $status;
protected $priority;
protected $title;
protected $description;
protected $attached = array();
protected $projectPHIDs = array();
public function getConfiguration() {
return array(
self::CONFIG_AUX_PHID => true,
self::CONFIG_SERIALIZATION => array(
'ccPHIDs' => self::SERIALIZATION_JSON,
'attached' => self::SERIALIZATION_JSON,
'projectPHIDs' => self::SERIALIZATION_JSON,
),
) + parent::getConfiguration();
}
public function getAttachedPHIDs($type) {
return array_keys(idx($this->attached, $type, array()));
}
public function generatePHID() {
- return PhabricatorPHID::generateNewPHID('TASK');
+ return PhabricatorPHID::generateNewPHID(
+ PhabricatorPHIDConstants::PHID_TYPE_TASK);
}
public function getCCPHIDs() {
return nonempty($this->ccPHIDs, array());
}
}
diff --git a/src/applications/maniphest/storage/task/__init__.php b/src/applications/maniphest/storage/task/__init__.php
index d8d7b7d38b..95791239e1 100644
--- a/src/applications/maniphest/storage/task/__init__.php
+++ b/src/applications/maniphest/storage/task/__init__.php
@@ -1,15 +1,16 @@
<?php
/**
* This file is automatically generated. Lint this module to rebuild it.
* @generated
*/
phutil_require_module('phabricator', 'applications/maniphest/storage/base');
+phutil_require_module('phabricator', 'applications/phid/constants');
phutil_require_module('phabricator', 'applications/phid/storage/phid');
phutil_require_module('phutil', 'utils');
phutil_require_source('ManiphestTask.php');
diff --git a/src/applications/maniphest/view/transactiondetail/ManiphestTransactionDetailView.php b/src/applications/maniphest/view/transactiondetail/ManiphestTransactionDetailView.php
index a90e0c852c..79f9bb866a 100644
--- a/src/applications/maniphest/view/transactiondetail/ManiphestTransactionDetailView.php
+++ b/src/applications/maniphest/view/transactiondetail/ManiphestTransactionDetailView.php
@@ -1,340 +1,341 @@
<?php
/*
* Copyright 2011 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.
*/
class ManiphestTransactionDetailView extends AphrontView {
private $transactions;
private $handles;
private $markupEngine;
private $forEmail;
public function setTransactionGroup(array $transactions) {
$this->transactions = $transactions;
return $this;
}
public function setHandles(array $handles) {
$this->handles = $handles;
return $this;
}
public function setMarkupEngine(PhutilMarkupEngine $engine) {
$this->markupEngine = $engine;
return $this;
}
public function renderForEmail($with_date) {
$this->forEmail = true;
$transaction = reset($this->transactions);
$author = $this->renderHandles(array($transaction->getAuthorPHID()));
$action = null;
$descs = array();
$comments = null;
foreach ($this->transactions as $transaction) {
list($verb, $desc, $classes) = $this->describeAction($transaction);
if ($action === null) {
$action = $verb;
}
$desc = $author.' '.$desc.'.';
if ($with_date) {
$desc = 'On '.date('M jS \a\t g:i A', $transaction->getDateCreated()).
', '.$desc;
}
$descs[] = $desc;
if ($transaction->hasComments()) {
$comments = $transaction->getComments();
}
}
$descs = implode("\n", $descs);
if ($comments) {
$descs .= "\n".$comments;
}
$this->forEmail = false;
return array($action, $descs);
}
public function render() {
$handles = $this->handles;
$transactions = $this->transactions;
require_celerity_resource('maniphest-transaction-detail-css');
$comment_transaction = null;
foreach ($this->transactions as $transaction) {
if ($transaction->hasComments()) {
$comment_transaction = $transaction;
break;
}
}
$any_transaction = reset($transactions);
$author = $this->handles[$any_transaction->getAuthorPHID()];
$more_classes = array();
$descs = array();
foreach ($transactions as $transaction) {
list($verb, $desc, $classes) = $this->describeAction($transaction);
$more_classes = array_merge($more_classes, $classes);
$descs[] = $author->renderLink().' '.$desc.'.';
}
$descs = implode('<br />', $descs);
$more_classes = implode(' ', $classes);
if ($comment_transaction && $comment_transaction->hasComments()) {
$comments = $comment_transaction->getCache();
if (!strlen($comments)) {
$comments = $comment_transaction->getComments();
if (strlen($comments)) {
$comments = $this->markupEngine->markupText($comments);
$comment_transaction->setCache($comments);
if ($comment_transaction->getID()) {
$comment_transaction->save();
}
}
}
$comment_block =
'<div class="maniphest-transaction-comments phabricator-remarkup">'.
$comments.
'</div>';
} else {
$comment_block = null;
}
return phutil_render_tag(
'div',
array(
'class' => "maniphest-transaction-detail-container",
'style' => "background-image: url('".$author->getImageURI()."')",
),
'<div class="maniphest-transaction-detail-view '.$more_classes.'">'.
'<div class="maniphest-transaction-header">'.
'<div class="maniphest-transaction-timestamp">'.
phabricator_format_timestamp($transaction->getDateCreated()).
'</div>'.
$descs.
'</div>'.
$comment_block.
'</div>');
}
private function describeAction($transaction) {
$verb = null;
$desc = null;
$classes = array();
$handles = $this->handles;
$type = $transaction->getTransactionType();
$author_phid = $transaction->getAuthorPHID();
$new = $transaction->getNewValue();
$old = $transaction->getOldValue();
switch ($type) {
case ManiphestTransactionType::TYPE_TITLE:
$verb = 'Retitled';
$desc = 'changed the title from '.$this->renderString($old).
' to '.$this->renderString($new);
break;
case ManiphestTransactionType::TYPE_DESCRIPTION:
// TODO: show the changes somehow.
$verb = 'Edited';
$desc = 'updated the task description';
break;
case ManiphestTransactionType::TYPE_NONE:
$verb = 'Commented On';
$desc = 'added a comment';
break;
case ManiphestTransactionType::TYPE_OWNER:
if ($transaction->getAuthorPHID() == $new) {
$verb = 'Claimed';
$desc = 'claimed this task';
} else if (!$new) {
$verb = 'Up For Grabs';
$desc = 'placed this task up for grabs';
} else if (!$old) {
$verb = 'Assigned';
$desc = 'assigned this task to '.$this->renderHandles(array($new));
} else {
$verb = 'Reassigned';
$desc = 'reassigned this task from '.
$this->renderHandles(array($old)).
' to '.
$this->renderHandles(array($new));
}
break;
case ManiphestTransactionType::TYPE_CCS:
$added = array_diff($new, $old);
$removed = array_diff($old, $new);
if ($added && !$removed) {
$verb = 'Added CC';
if (count($added) == 1) {
$desc = 'added '.$this->renderHandles($added).' to CC';
} else {
$desc = 'added CCs: '.$this->renderHandles($added);
}
} else if ($removed && !$added) {
$verb = 'Removed CC';
if (count($removed) == 1) {
$desc = 'removed '.$this->renderHandles($removed).' from CC';
} else {
$desc = 'removed CCs: '.$this->renderHandles($removed);
}
} else {
$verb = 'Changed CC';
$desc = 'changed CCs, added: '.$this->renderHandles($added).'; '.
'removed: '.$this->renderHandles($removed);
}
break;
case ManiphestTransactionType::TYPE_PROJECTS:
$added = array_diff($new, $old);
$removed = array_diff($old, $new);
if ($added && !$removed) {
$verb = 'Added Project';
if (count($added) == 1) {
$desc = 'added project '.$this->renderHandles($added);
} else {
$desc = 'added projects: '.$this->renderHandles($added);
}
} else if ($removed && !$added) {
$verb = 'Removed Project';
if (count($removed) == 1) {
$desc = 'removed project '.$this->renderHandles($removed);
} else {
$desc = 'removed projectss: '.$this->renderHandles($removed);
}
} else {
$verb = 'Changed Projects';
$desc = 'changed projects, added: '.$this->renderHandles($added).'; '.
'removed: '.$this->renderHandles($removed);
}
break;
case ManiphestTransactionType::TYPE_STATUS:
if ($new == ManiphestTaskStatus::STATUS_OPEN) {
if ($old) {
$verb = 'Reopened';
$desc = 'reopened this task';
} else {
$verb = 'Created';
$desc = 'created this task';
}
} else if ($new == ManiphestTaskStatus::STATUS_CLOSED_SPITE) {
$verb = 'Spited';
$desc = 'closed this task out of spite';
} else {
$verb = 'Closed';
$full = idx(ManiphestTaskStatus::getTaskStatusMap(), $new, '???');
$desc = 'closed this task as "'.$full.'"';
}
break;
case ManiphestTransactionType::TYPE_PRIORITY:
$old_name = ManiphestTaskPriority::getTaskPriorityName($old);
$new_name = ManiphestTaskPriority::getTaskPriorityName($new);
if ($old == ManiphestTaskPriority::PRIORITY_TRIAGE) {
$verb = 'Triaged';
$desc = 'triaged this task as "'.$new_name.'" priority';
} else if ($old > $new) {
$verb = 'Lowered Priority';
$desc = 'lowered the priority of this task from "'.$old_name.'" to '.
'"'.$new_name.'"';
} else {
$verb = 'Raised Priority';
$desc = 'raised the priority of this task from "'.$old_name.'" to '.
'"'.$new_name.'"';
}
break;
case ManiphestTransactionType::TYPE_ATTACH:
$old_raw = nonempty($old, array());
$new_raw = nonempty($new, array());
- foreach (array('DREV', 'FILE') as $type) {
+ foreach (array(PhabricatorPHIDConstants::PHID_TYPE_DREV,
+ PhabricatorPHIDConstants::PHID_TYPE_FILE) as $type) {
$old = array_keys(idx($old_raw, $type, array()));
$new = array_keys(idx($new_raw, $type, array()));
if ($old != $new) {
break;
}
}
$added = array_diff($new, $old);
$removed = array_diff($old, $new);
$add_desc = $this->renderHandles($added);
$rem_desc = $this->renderHandles($removed);
switch ($type) {
- case 'DREV':
+ case PhabricatorPHIDConstants::PHID_TYPE_DREV:
$singular = 'Differential Revision';
$plural = 'Differential Revisions';
break;
- case 'FILE':
+ case PhabricatorPHIDConstants::PHID_TYPE_FILE:
$singular = 'file';
$plural = 'files';
break;
}
if ($added && !$removed) {
$verb = 'Attached';
if (count($added) == 1) {
$desc = 'attached '.$singular.': '.$add_desc;
} else {
$desc = 'attached '.$plural.': '.$add_desc;
}
} else if ($removed && !$added) {
$verb = 'Detached';
if (count($removed) == 1) {
$desc = 'detached '.$singular.': '.$rem_desc;
} else {
$desc = 'detached '.$plural.': '.$rem_desc;
}
} else {
$desc = 'changed attached '.$plural.', added: '.$add_desc.
'removed: '.$rem_desc;
}
break;
default:
return array($type, ' brazenly '.$type."'d", $classes);
}
return array($verb, $desc, $classes);
}
private function renderHandles($phids) {
$links = array();
foreach ($phids as $phid) {
if ($this->forEmail) {
$links[] = $this->handles[$phid]->getName();
} else {
$links[] = $this->handles[$phid]->renderLink();
}
}
return implode(', ', $links);
}
private function renderString($string) {
if ($this->forEmail) {
return '"'.$string.'"';
} else {
return '"'.phutil_escape_html($string).'"';
}
}
}
diff --git a/src/applications/maniphest/view/transactiondetail/__init__.php b/src/applications/maniphest/view/transactiondetail/__init__.php
index 9f08794372..a5700bb1af 100644
--- a/src/applications/maniphest/view/transactiondetail/__init__.php
+++ b/src/applications/maniphest/view/transactiondetail/__init__.php
@@ -1,20 +1,21 @@
<?php
/**
* This file is automatically generated. Lint this module to rebuild it.
* @generated
*/
phutil_require_module('phabricator', 'applications/maniphest/constants/priority');
phutil_require_module('phabricator', 'applications/maniphest/constants/status');
phutil_require_module('phabricator', 'applications/maniphest/constants/transactiontype');
+phutil_require_module('phabricator', 'applications/phid/constants');
phutil_require_module('phabricator', 'infrastructure/celerity/api');
phutil_require_module('phabricator', 'view/base');
phutil_require_module('phabricator', 'view/utils');
phutil_require_module('phutil', 'markup');
phutil_require_module('phutil', 'utils');
phutil_require_source('ManiphestTransactionDetailView.php');
diff --git a/src/applications/metamta/storage/mailinglist/PhabricatorMetaMTAMailingList.php b/src/applications/metamta/storage/mailinglist/PhabricatorMetaMTAMailingList.php
index c8df2e35ab..49bbff7bfd 100644
--- a/src/applications/metamta/storage/mailinglist/PhabricatorMetaMTAMailingList.php
+++ b/src/applications/metamta/storage/mailinglist/PhabricatorMetaMTAMailingList.php
@@ -1,38 +1,37 @@
<?php
/*
* Copyright 2011 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.
*/
class PhabricatorMetaMTAMailingList extends PhabricatorMetaMTADAO {
- const TYPE_MAILING_LIST = 'MLST';
-
protected $name;
protected $phid;
protected $email;
protected $uri;
public function generatePHID() {
- return PhabricatorPHID::generateNewPHID(self::TYPE_MAILING_LIST);
+ return PhabricatorPHID::generateNewPHID(
+ PhabricatorPHIDConstants::PHID_TYPE_MLST);
}
public function getConfiguration() {
return array(
self::CONFIG_AUX_PHID => true,
) + parent::getConfiguration();
}
}
diff --git a/src/applications/metamta/storage/mailinglist/__init__.php b/src/applications/metamta/storage/mailinglist/__init__.php
index 6ca6793cb3..62022bbceb 100644
--- a/src/applications/metamta/storage/mailinglist/__init__.php
+++ b/src/applications/metamta/storage/mailinglist/__init__.php
@@ -1,13 +1,14 @@
<?php
/**
* This file is automatically generated. Lint this module to rebuild it.
* @generated
*/
phutil_require_module('phabricator', 'applications/metamta/storage/base');
+phutil_require_module('phabricator', 'applications/phid/constants');
phutil_require_module('phabricator', 'applications/phid/storage/phid');
phutil_require_source('PhabricatorMetaMTAMailingList.php');
diff --git a/src/applications/people/storage/user/PhabricatorUser.php b/src/applications/people/storage/user/PhabricatorUser.php
index f14d251952..bccb7d565d 100644
--- a/src/applications/people/storage/user/PhabricatorUser.php
+++ b/src/applications/people/storage/user/PhabricatorUser.php
@@ -1,165 +1,164 @@
<?php
/*
* Copyright 2011 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.
*/
class PhabricatorUser extends PhabricatorUserDAO {
- const PHID_TYPE = 'USER';
-
const SESSION_TABLE = 'phabricator_session';
protected $phid;
protected $userName;
protected $realName;
protected $email;
protected $passwordSalt;
protected $passwordHash;
protected $profileImagePHID;
protected $consoleEnabled = 0;
protected $consoleVisible = 0;
protected $consoleTab = '';
protected $conduitCertificate;
public function getProfileImagePHID() {
return nonempty(
$this->profileImagePHID,
PhabricatorEnv::getEnvConfig('user.default-profile-image-phid'));
}
public function getConfiguration() {
return array(
self::CONFIG_AUX_PHID => true,
) + parent::getConfiguration();
}
public function generatePHID() {
- return PhabricatorPHID::generateNewPHID(self::PHID_TYPE);
+ return PhabricatorPHID::generateNewPHID(
+ PhabricatorPHIDConstants::PHID_TYPE_USER);
}
public function setPassword($password) {
$this->setPasswordSalt(md5(mt_rand()));
$hash = $this->hashPassword($password);
$this->setPasswordHash($hash);
return $this;
}
public function save() {
if (!$this->conduitCertificate) {
$this->conduitCertificate = $this->generateConduitCertificate();
}
return parent::save();
}
private function generateConduitCertificate() {
$entropy = Filesystem::readRandomBytes(256);
$entropy = base64_encode($entropy);
$entropy = substr($entropy, 0, 255);
return $entropy;
}
public function comparePassword($password) {
$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) {
for ($ii = -1; $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->passwordHash.$key.$time_block;
return substr(sha1($vec), 0, $len);
}
public function establishSession($session_type) {
$conn_w = $this->establishConnection('w');
$entropy = Filesystem::readRandomBytes(20);
$session_key = sha1($entropy);
queryfx(
$conn_w,
'INSERT INTO %T '.
'(userPHID, type, sessionKey, sessionStart)'.
' VALUES '.
'(%s, %s, %s, UNIX_TIMESTAMP()) '.
'ON DUPLICATE KEY UPDATE '.
'sessionKey = VALUES(sessionKey), '.
'sessionStart = VALUES(sessionStart)',
self::SESSION_TABLE,
$this->getPHID(),
$session_type,
$session_key);
$this->sessionKey = $session_key;
return $session_key;
}
public function generateEmailToken($offset = 0) {
return $this->generateToken(
time() + ($offset * self::EMAIL_CYCLE_FREQUENCY),
self::EMAIL_CYCLE_FREQUENCY,
PhabricatorEnv::getEnvConfig('phabricator.csrf-key').$this->getEmail(),
self::EMAIL_TOKEN_LENGTH);
}
public function validateEmailToken($token) {
for ($ii = -1; $ii <= 1; $ii++) {
$valid = $this->generateEmailToken($ii);
if ($token == $valid) {
return true;
}
}
return false;
}
}
diff --git a/src/applications/people/storage/user/__init__.php b/src/applications/people/storage/user/__init__.php
index 3be82cddf2..efe13374b1 100644
--- a/src/applications/people/storage/user/__init__.php
+++ b/src/applications/people/storage/user/__init__.php
@@ -1,18 +1,19 @@
<?php
/**
* This file is automatically generated. Lint this module to rebuild it.
* @generated
*/
phutil_require_module('phabricator', 'applications/people/storage/base');
+phutil_require_module('phabricator', 'applications/phid/constants');
phutil_require_module('phabricator', 'applications/phid/storage/phid');
phutil_require_module('phabricator', 'infrastructure/env');
phutil_require_module('phabricator', 'storage/queryfx');
phutil_require_module('phutil', 'filesystem');
phutil_require_module('phutil', 'utils');
phutil_require_source('PhabricatorUser.php');
diff --git a/src/applications/project/storage/project/PhabricatorProject.php b/src/applications/phid/constants/PhabricatorPHIDConstants.php
similarity index 63%
copy from src/applications/project/storage/project/PhabricatorProject.php
copy to src/applications/phid/constants/PhabricatorPHIDConstants.php
index 3263270acb..e8363a9d71 100644
--- a/src/applications/project/storage/project/PhabricatorProject.php
+++ b/src/applications/phid/constants/PhabricatorPHIDConstants.php
@@ -1,35 +1,30 @@
<?php
/*
* Copyright 2011 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.
*/
-class PhabricatorProject extends PhabricatorProjectDAO {
+final class PhabricatorPHIDConstants {
- protected $name;
- protected $phid;
- protected $authorPHID;
-
- public function getConfiguration() {
- return array(
- self::CONFIG_AUX_PHID => true,
- ) + parent::getConfiguration();
- }
-
- public function generatePHID() {
- return PhabricatorPHID::generateNewPHID('PROJ');
- }
+ const PHID_TYPE_USER = 'USER';
+ const PHID_TYPE_MLST = 'MLST';
+ const PHID_TYPE_DREV = 'DREV';
+ const PHID_TYPE_TASK = 'TASK';
+ const PHID_TYPE_FILE = 'FILE';
+ const PHID_TYPE_PROJ = 'PROJ';
+ const PHID_TYPE_UNKNOWN = '????';
+ const PHID_TYPE_MAGIC = '!!!!';
}
diff --git a/src/applications/phid/handle/__init__.php b/src/applications/phid/constants/__init__.php
similarity index 51%
copy from src/applications/phid/handle/__init__.php
copy to src/applications/phid/constants/__init__.php
index 781f961e90..eea1fa0c46 100644
--- a/src/applications/phid/handle/__init__.php
+++ b/src/applications/phid/constants/__init__.php
@@ -1,12 +1,10 @@
<?php
/**
* This file is automatically generated. Lint this module to rebuild it.
* @generated
*/
-phutil_require_module('phutil', 'markup');
-
-phutil_require_source('PhabricatorObjectHandle.php');
+phutil_require_source('PhabricatorPHIDConstants.php');
diff --git a/src/applications/phid/handle/PhabricatorObjectHandle.php b/src/applications/phid/handle/PhabricatorObjectHandle.php
index 55a57d5641..aaad0886fd 100644
--- a/src/applications/phid/handle/PhabricatorObjectHandle.php
+++ b/src/applications/phid/handle/PhabricatorObjectHandle.php
@@ -1,113 +1,113 @@
<?php
/*
* Copyright 2011 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.
*/
class PhabricatorObjectHandle {
private $uri;
private $phid;
private $type;
private $name;
private $email;
private $fullName;
private $imageURI;
public function setURI($uri) {
$this->uri = $uri;
return $this;
}
public function getURI() {
return $this->uri;
}
public function setPHID($phid) {
$this->phid = $phid;
return $this;
}
public function getPHID() {
return $this->phid;
}
public function setName($name) {
$this->name = $name;
return $this;
}
public function getName() {
return $this->name;
}
public function setFullName($full_name) {
$this->fullName = $full_name;
return $this;
}
public function getFullName() {
if ($this->fullName !== null) {
return $this->fullName;
}
return $this->getName();
}
public function setType($type) {
$this->type = $type;
return $this;
}
public function getType() {
return $this->type;
}
public function setEmail($email) {
$this->email = $email;
return $this;
}
public function getEmail() {
return $this->email;
}
public function setImageURI($uri) {
$this->imageURI = $uri;
return $this;
}
public function getImageURI() {
return $this->imageURI;
}
public function renderLink() {
switch ($this->getType()) {
- case 'USER':
+ case PhabricatorPHIDConstants::PHID_TYPE_USER:
$name = $this->getName();
break;
default:
$name = $this->getFullName();
}
return phutil_render_tag(
'a',
array(
'href' => $this->getURI(),
),
phutil_escape_html($name));
}
}
diff --git a/src/applications/phid/handle/__init__.php b/src/applications/phid/handle/__init__.php
index 781f961e90..4d4b4ebbad 100644
--- a/src/applications/phid/handle/__init__.php
+++ b/src/applications/phid/handle/__init__.php
@@ -1,12 +1,14 @@
<?php
/**
* This file is automatically generated. Lint this module to rebuild it.
* @generated
*/
+phutil_require_module('phabricator', 'applications/phid/constants');
+
phutil_require_module('phutil', 'markup');
phutil_require_source('PhabricatorObjectHandle.php');
diff --git a/src/applications/phid/handle/data/PhabricatorObjectHandleData.php b/src/applications/phid/handle/data/PhabricatorObjectHandleData.php
index 72433f3315..3445629d9d 100644
--- a/src/applications/phid/handle/data/PhabricatorObjectHandleData.php
+++ b/src/applications/phid/handle/data/PhabricatorObjectHandleData.php
@@ -1,228 +1,226 @@
<?php
/*
* Copyright 2011 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.
*/
class PhabricatorObjectHandleData {
- const TYPE_UNKNOWN = '????';
-
private $phids;
public function __construct(array $phids) {
$this->phids = $phids;
}
public function loadHandles() {
$types = array();
foreach ($this->phids as $phid) {
$type = $this->lookupType($phid);
$types[$type][] = $phid;
}
$handles = array();
foreach ($types as $type => $phids) {
switch ($type) {
- case '!!!!':
+ case PhabricatorPHIDConstants::PHID_TYPE_MAGIC:
// Black magic!
foreach ($phids as $phid) {
$handle = new PhabricatorObjectHandle();
$handle->setPHID($phid);
$handle->setType($type);
switch ($phid) {
case 'PHID-!!!!-UP-FOR-GRABS':
$handle->setName('Up For Grabs');
break;
default:
$handle->setName('Foul Magicks');
break;
}
$handles[$phid] = $handle;
}
break;
- case 'USER':
+ case PhabricatorPHIDConstants::PHID_TYPE_USER:
$class = 'PhabricatorUser';
PhutilSymbolLoader::loadClass($class);
$object = newv($class, array());
$users = $object->loadAllWhere('phid IN (%Ls)', $phids);
$users = mpull($users, null, 'getPHID');
foreach ($phids as $phid) {
$handle = new PhabricatorObjectHandle();
$handle->setPHID($phid);
$handle->setType($type);
if (empty($users[$phid])) {
$handle->setName('Unknown User');
} else {
$user = $users[$phid];
$handle->setName($user->getUsername());
$handle->setURI('/p/'.$user->getUsername().'/');
$handle->setEmail($user->getEmail());
$handle->setFullName(
$user->getUsername().' ('.$user->getRealName().')');
$img_phid = $user->getProfileImagePHID();
if ($img_phid) {
$handle->setImageURI(
PhabricatorFileURI::getViewURIForPHID($img_phid));
}
}
$handles[$phid] = $handle;
}
break;
- case 'MLST':
+ case PhabricatorPHIDConstants::PHID_TYPE_MLST:
$class = 'PhabricatorMetaMTAMailingList';
PhutilSymbolLoader::loadClass($class);
$object = newv($class, array());
$lists = $object->loadAllWhere('phid IN (%Ls)', $phids);
$lists = mpull($lists, null, 'getPHID');
foreach ($phids as $phid) {
$handle = new PhabricatorObjectHandle();
$handle->setPHID($phid);
$handle->setType($type);
if (empty($lists[$phid])) {
$handle->setName('Unknown Mailing List');
} else {
$list = $lists[$phid];
$handle->setEmail($list->getEmail());
$handle->setName($list->getName());
$handle->setURI($list->getURI());
$handle->setFullName($list->getName());
}
$handles[$phid] = $handle;
}
break;
- case 'DREV':
+ case PhabricatorPHIDConstants::PHID_TYPE_DREV:
$class = 'DifferentialRevision';
PhutilSymbolLoader::loadClass($class);
$object = newv($class, array());
$revs = $object->loadAllWhere('phid in (%Ls)', $phids);
$revs = mpull($revs, null, 'getPHID');
foreach ($phids as $phid) {
$handle = new PhabricatorObjectHandle();
$handle->setPHID($phid);
$handle->setType($type);
if (empty($revs[$phid])) {
$handle->setName('Unknown Revision');
} else {
$rev = $revs[$phid];
$handle->setName($rev->getTitle());
$handle->setURI('/D'.$rev->getID());
$handle->setFullName('D'.$rev->getID().': '.$rev->getTitle());
}
$handles[$phid] = $handle;
}
break;
- case 'TASK':
+ case PhabricatorPHIDConstants::PHID_TYPE_TASK:
$class = 'ManiphestTask';
PhutilSymbolLoader::loadClass($class);
$object = newv($class, array());
$tasks = $object->loadAllWhere('phid in (%Ls)', $phids);
$tasks = mpull($tasks, null, 'getPHID');
foreach ($phids as $phid) {
$handle = new PhabricatorObjectHandle();
$handle->setPHID($phid);
$handle->setType($type);
if (empty($tasks[$phid])) {
$handle->setName('Unknown Revision');
} else {
$task = $tasks[$phid];
$handle->setName($task->getTitle());
$handle->setURI('/T'.$task->getID());
$handle->setFullName('T'.$task->getID().': '.$task->getTitle());
}
$handles[$phid] = $handle;
}
break;
- case 'FILE':
+ case PhabricatorPHIDConstants::PHID_TYPE_FILE:
$class = 'PhabricatorFile';
PhutilSymbolLoader::loadClass($class);
$object = newv($class, array());
$files = $object->loadAllWhere('phid IN (%Ls)', $phids);
$files = mpull($files, null, 'getPHID');
foreach ($phids as $phid) {
$handle = new PhabricatorObjectHandle();
$handle->setPHID($phid);
$handle->setType($type);
if (empty($files[$phid])) {
$handle->setName('Unknown File');
} else {
$file = $files[$phid];
$handle->setName($file->getName());
$handle->setURI($file->getViewURI());
}
$handles[$phid] = $handle;
}
break;
- case 'PROJ':
+ case PhabricatorPHIDConstants::PHID_TYPE_PROJ:
$class = 'PhabricatorProject';
PhutilSymbolLoader::loadClass($class);
$object = newv($class, array());
$projects = $object->loadAllWhere('phid IN (%Ls)', $phids);
$projects = mpull($projects, null, 'getPHID');
foreach ($phids as $phid) {
$handle = new PhabricatorObjectHandle();
$handle->setPHID($phid);
$handle->setType($type);
if (empty($projects[$phid])) {
$handle->setName('Unknown Project');
} else {
$project = $projects[$phid];
$handle->setName($project->getName());
$handle->setURI('/project/view/'.$project->getID().'/');
}
$handles[$phid] = $handle;
}
break;
default:
foreach ($phids as $phid) {
$handle = new PhabricatorObjectHandle();
$handle->setType($type);
$handle->setPHID($phid);
$handle->setName('Unknown Object');
$handle->setFullName('An Unknown Object');
$handles[$phid] = $handle;
}
break;
}
}
return $handles;
}
private function lookupType($phid) {
$matches = null;
if (preg_match('/^PHID-([^-]{4})-/', $phid, $matches)) {
return $matches[1];
}
- return self::TYPE_UNKNOWN;
+ return PhabricatorPHIDConstants::PHID_TYPE_UNKNOWN;
}
}
diff --git a/src/applications/phid/handle/data/__init__.php b/src/applications/phid/handle/data/__init__.php
index a80c17a0cb..b01d560e70 100644
--- a/src/applications/phid/handle/data/__init__.php
+++ b/src/applications/phid/handle/data/__init__.php
@@ -1,16 +1,17 @@
<?php
/**
* This file is automatically generated. Lint this module to rebuild it.
* @generated
*/
phutil_require_module('phabricator', 'applications/files/uri');
+phutil_require_module('phabricator', 'applications/phid/constants');
phutil_require_module('phabricator', 'applications/phid/handle');
phutil_require_module('phutil', 'symbols');
phutil_require_module('phutil', 'utils');
phutil_require_source('PhabricatorObjectHandleData.php');
diff --git a/src/applications/project/storage/project/PhabricatorProject.php b/src/applications/project/storage/project/PhabricatorProject.php
index 3263270acb..3064c20207 100644
--- a/src/applications/project/storage/project/PhabricatorProject.php
+++ b/src/applications/project/storage/project/PhabricatorProject.php
@@ -1,35 +1,36 @@
<?php
/*
* Copyright 2011 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.
*/
class PhabricatorProject extends PhabricatorProjectDAO {
protected $name;
protected $phid;
protected $authorPHID;
public function getConfiguration() {
return array(
self::CONFIG_AUX_PHID => true,
) + parent::getConfiguration();
}
public function generatePHID() {
- return PhabricatorPHID::generateNewPHID('PROJ');
+ return PhabricatorPHID::generateNewPHID(
+ PhabricatorPHIDConstants::PHID_TYPE_PROJ);
}
}
diff --git a/src/applications/project/storage/project/__init__.php b/src/applications/project/storage/project/__init__.php
index 89105fe95c..f378038d02 100644
--- a/src/applications/project/storage/project/__init__.php
+++ b/src/applications/project/storage/project/__init__.php
@@ -1,13 +1,14 @@
<?php
/**
* This file is automatically generated. Lint this module to rebuild it.
* @generated
*/
+phutil_require_module('phabricator', 'applications/phid/constants');
phutil_require_module('phabricator', 'applications/phid/storage/phid');
phutil_require_module('phabricator', 'applications/project/storage/base');
phutil_require_source('PhabricatorProject.php');
diff --git a/src/applications/search/controller/search/PhabricatorSearchController.php b/src/applications/search/controller/search/PhabricatorSearchController.php
index 4898f01df4..f982706832 100644
--- a/src/applications/search/controller/search/PhabricatorSearchController.php
+++ b/src/applications/search/controller/search/PhabricatorSearchController.php
@@ -1,182 +1,182 @@
<?php
/*
* Copyright 2011 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.
*/
class PhabricatorSearchController extends PhabricatorSearchBaseController {
private $id;
public function willProcessRequest(array $data) {
$this->id = idx($data, 'id');
}
public function processRequest() {
$request = $this->getRequest();
$user = $request->getUser();
if ($this->id) {
$query = id(new PhabricatorSearchQuery())->load($this->id);
if (!$query) {
return new Aphront404Response();
}
} else {
$query = new PhabricatorSearchQuery();
if ($request->isFormPost()) {
$query->setQuery($request->getStr('query'));
if (strlen($request->getStr('type'))) {
$query->setParameter('type', $request->getStr('type'));
}
if ($request->getArr('author')) {
$query->setParameter('author', $request->getArr('author'));
}
if ($request->getArr('owner')) {
$query->setParameter('owner', $request->getArr('owner'));
}
if ($request->getInt('open')) {
$query->setParameter('open', $request->getInt('open'));
}
if ($request->getArr('project')) {
$query->setParameter('project', $request->getArr('project'));
}
$query->save();
return id(new AphrontRedirectResponse())
->setURI('/search/'.$query->getID().'/');
}
}
$options = array(
'' => 'All Documents',
- 'DREV' => 'Differential Revisions',
- 'TASK' => 'Maniphest Tasks',
+ PhabricatorPHIDConstants::PHID_TYPE_DREV => 'Differential Revisions',
+ PhabricatorPHIDConstants::PHID_TYPE_TASK => 'Maniphest Tasks',
);
$status_options = array(
0 => 'Open and Closed Documents',
1 => 'Open Documents',
);
$phids = array_merge(
$query->getParameter('author', array()),
$query->getParameter('owner', array()),
$query->getParameter('project', array())
);
$handles = id(new PhabricatorObjectHandleData($phids))
->loadHandles();
$author_value = array_select_keys(
$handles,
$query->getParameter('author', array()));
$author_value = mpull($author_value, 'getFullName', 'getPHID');
$owner_value = array_select_keys(
$handles,
$query->getParameter('owner', array()));
$owner_value = mpull($owner_value, 'getFullName', 'getPHID');
$project_value = array_select_keys(
$handles,
$query->getParameter('project', array()));
$project_value = mpull($project_value, 'getFullName', 'getPHID');
$search_form = new AphrontFormView();
$search_form
->setUser($user)
->setAction('/search/')
->appendChild(
id(new AphrontFormTextControl())
->setLabel('Search')
->setName('query')
->setValue($query->getQuery()))
->appendChild(
id(new AphrontFormSelectControl())
->setLabel('Document Type')
->setName('type')
->setOptions($options)
->setValue($query->getParameter('type')))
->appendChild(
id(new AphrontFormSelectControl())
->setLabel('Document Status')
->setName('open')
->setOptions($status_options)
->setValue($query->getParameter('open')))
->appendChild(
id(new AphrontFormTokenizerControl())
->setName('author')
->setLabel('Author')
->setDatasource('/typeahead/common/users/')
->setValue($author_value))
->appendChild(
id(new AphrontFormTokenizerControl())
->setName('owner')
->setLabel('Owner')
->setDatasource('/typeahead/common/searchowner/')
->setValue($owner_value)
->setCaption(
'Tip: search for "Up For Grabs" to find unowned documents.'))
->appendChild(
id(new AphrontFormTokenizerControl())
->setName('project')
->setLabel('Project')
->setDatasource('/typeahead/common/projects/')
->setValue($project_value))
->appendChild(
id(new AphrontFormSubmitControl())
->setValue('Search'));
$search_panel = new AphrontPanelView();
$search_panel->setHeader('Search Phabricator');
$search_panel->appendChild($search_form);
if ($query->getID()) {
$executor = new PhabricatorSearchMySQLExecutor();
$results = $executor->executeSearch($query);
$results = ipull($results, 'phid');
$handles = id(new PhabricatorObjectHandleData($results))
->loadHandles();
$results = array();
foreach ($handles as $handle) {
$results[] = '<h1>'.$handle->renderLink().'</h1>';
}
$results =
'<div style="padding: 1em 2em 2em;">'.
implode("\n", $results).
'</div>';
} else {
$results = null;
}
$results = print_r($results, true);
return $this->buildStandardPageResponse(
array(
$search_panel,
$results,
),
array(
'title' => 'Results: what',
));
}
}
diff --git a/src/applications/search/controller/search/__init__.php b/src/applications/search/controller/search/__init__.php
index a116849ddf..c91e268a6f 100644
--- a/src/applications/search/controller/search/__init__.php
+++ b/src/applications/search/controller/search/__init__.php
@@ -1,22 +1,23 @@
<?php
/**
* This file is automatically generated. Lint this module to rebuild it.
* @generated
*/
phutil_require_module('phabricator', 'aphront/response/404');
phutil_require_module('phabricator', 'aphront/response/redirect');
+phutil_require_module('phabricator', 'applications/phid/constants');
phutil_require_module('phabricator', 'applications/phid/handle/data');
phutil_require_module('phabricator', 'applications/search/controller/base');
phutil_require_module('phabricator', 'applications/search/execute/mysql');
phutil_require_module('phabricator', 'applications/search/storage/query');
phutil_require_module('phabricator', 'view/form/base');
phutil_require_module('phabricator', 'view/form/control/submit');
phutil_require_module('phabricator', 'view/layout/panel');
phutil_require_module('phutil', 'utils');
phutil_require_source('PhabricatorSearchController.php');
diff --git a/src/applications/search/index/indexer/differential/PhabricatorSearchDifferentialIndexer.php b/src/applications/search/index/indexer/differential/PhabricatorSearchDifferentialIndexer.php
index 8e0af71606..e22f7308cb 100644
--- a/src/applications/search/index/indexer/differential/PhabricatorSearchDifferentialIndexer.php
+++ b/src/applications/search/index/indexer/differential/PhabricatorSearchDifferentialIndexer.php
@@ -1,102 +1,102 @@
<?php
/*
* Copyright 2011 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.
*/
class PhabricatorSearchDifferentialIndexer
extends PhabricatorSearchDocumentIndexer {
public static function indexRevision(DifferentialRevision $rev) {
$doc = new PhabricatorSearchAbstractDocument();
$doc->setPHID($rev->getPHID());
- $doc->setDocumentType('DREV');
+ $doc->setDocumentType(PhabricatorPHIDConstants::PHID_TYPE_DREV);
$doc->setDocumentTitle($rev->getTitle());
$doc->setDocumentCreated($rev->getDateCreated());
$doc->setDocumentModified($rev->getDateModified());
$doc->addField(
PhabricatorSearchField::FIELD_BODY,
$rev->getSummary());
$doc->addField(
PhabricatorSearchField::FIELD_TEST_PLAN,
$rev->getTestPlan());
$doc->addRelationship(
PhabricatorSearchRelationship::RELATIONSHIP_AUTHOR,
$rev->getAuthorPHID(),
- 'USER',
+ PhabricatorPHIDConstants::PHID_TYPE_USER,
$rev->getDateCreated());
if ($rev->getStatus() != DifferentialRevisionStatus::COMMITTED &&
$rev->getStatus() != DifferentialRevisionStatus::ABANDONED) {
$doc->addRelationship(
PhabricatorSearchRelationship::RELATIONSHIP_OPEN,
$rev->getPHID(),
- 'DREV',
+ PhabricatorPHIDConstants::PHID_TYPE_DREV,
time());
}
$comments = id(new DifferentialInlineComment())->loadAllWhere(
'revisionID = %d AND commentID is not null',
$rev->getID());
$touches = array();
foreach ($comments as $comment) {
if (strlen($comment->getContent())) {
// TODO: we should also index inline comments.
$doc->addField(
PhabricatorSearchField::FIELD_COMMENT,
$comment->getContent());
}
$author = $comment->getAuthorPHID();
$touches[$author] = $comment->getDateCreated();
}
foreach ($touches as $touch => $time) {
$doc->addRelationship(
PhabricatorSearchRelationship::RELATIONSHIP_TOUCH,
$touch,
- 'USER',
+ PhabricatorPHIDConstants::PHID_TYPE_USER,
$time);
}
$rev->loadRelationships();
foreach ($rev->getReviewers() as $phid) {
$doc->addRelationship(
PhabricatorSearchRelationship::RELATIONSHIP_OWNER,
$phid,
- 'USER',
+ PhabricatorPHIDConstants::PHID_TYPE_USER,
$rev->getDateModified()); // Bogus timestamp.
}
$ccphids = $rev->getCCPHIDs();
$handles = id(new PhabricatorObjectHandleData($ccphids))
->loadHandles();
foreach ($handles as $phid => $handle) {
$doc->addRelationship(
PhabricatorSearchRelationship::RELATIONSHIP_SUBSCRIBER,
$phid,
$handle->getType(),
$rev->getDateModified()); // Bogus timestamp.
}
PhabricatorSearchDocument::reindexAbstractDocument($doc);
}
}
diff --git a/src/applications/search/index/indexer/differential/__init__.php b/src/applications/search/index/indexer/differential/__init__.php
index 9dda223db2..bb280993f1 100644
--- a/src/applications/search/index/indexer/differential/__init__.php
+++ b/src/applications/search/index/indexer/differential/__init__.php
@@ -1,21 +1,22 @@
<?php
/**
* This file is automatically generated. Lint this module to rebuild it.
* @generated
*/
phutil_require_module('phabricator', 'applications/differential/constants/revisionstatus');
phutil_require_module('phabricator', 'applications/differential/storage/inlinecomment');
+phutil_require_module('phabricator', 'applications/phid/constants');
phutil_require_module('phabricator', 'applications/phid/handle/data');
phutil_require_module('phabricator', 'applications/search/constants/field');
phutil_require_module('phabricator', 'applications/search/constants/relationship');
phutil_require_module('phabricator', 'applications/search/index/abstractdocument');
phutil_require_module('phabricator', 'applications/search/index/indexer/base');
phutil_require_module('phabricator', 'applications/search/storage/document/document');
phutil_require_module('phutil', 'utils');
phutil_require_source('PhabricatorSearchDifferentialIndexer.php');
diff --git a/src/applications/search/index/indexer/maniphest/PhabricatorSearchManiphestIndexer.php b/src/applications/search/index/indexer/maniphest/PhabricatorSearchManiphestIndexer.php
index b6e0af88e6..f4bf4cca02 100644
--- a/src/applications/search/index/indexer/maniphest/PhabricatorSearchManiphestIndexer.php
+++ b/src/applications/search/index/indexer/maniphest/PhabricatorSearchManiphestIndexer.php
@@ -1,132 +1,132 @@
<?php
/*
* Copyright 2011 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.
*/
class PhabricatorSearchManiphestIndexer
extends PhabricatorSearchDocumentIndexer {
public static function indexTask(ManiphestTask $task) {
$doc = new PhabricatorSearchAbstractDocument();
$doc->setPHID($task->getPHID());
- $doc->setDocumentType('TASK');
+ $doc->setDocumentType(PhabricatorPHIDConstants::PHID_TYPE_TASK);
$doc->setDocumentTitle($task->getTitle());
$doc->setDocumentCreated($task->getDateCreated());
$doc->setDocumentModified($task->getDateModified());
$doc->addField(
PhabricatorSearchField::FIELD_BODY,
$task->getDescription());
$doc->addRelationship(
PhabricatorSearchRelationship::RELATIONSHIP_AUTHOR,
$task->getAuthorPHID(),
- 'USER',
+ PhabricatorPHIDConstants::PHID_TYPE_USER,
$task->getDateCreated());
if ($task->getStatus() == ManiphestTaskStatus::STATUS_OPEN) {
$doc->addRelationship(
PhabricatorSearchRelationship::RELATIONSHIP_OPEN,
$task->getPHID(),
- 'TASK',
+ PhabricatorPHIDConstants::PHID_TYPE_TASK,
time());
}
$transactions = id(new ManiphestTransaction())->loadAllWhere(
'taskID = %d',
$task->getID());
$current_ccs = $task->getCCPHIDs();
$touches = array();
$owner = null;
$ccs = array();
foreach ($transactions as $transaction) {
if ($transaction->hasComments()) {
$doc->addField(
PhabricatorSearchField::FIELD_COMMENT,
$transaction->getComments());
}
$author = $transaction->getAuthorPHID();
// Record the most recent time they touched this object.
$touches[$author] = $transaction->getDateCreated();
switch ($transaction->getTransactionType()) {
case ManiphestTransactionType::TYPE_OWNER:
$owner = $transaction;
break;
case ManiphestTransactionType::TYPE_CCS:
// For users who are still CC'd, record the first time they were
// added to CC.
foreach ($transaction->getNewValue() as $added_cc) {
if (in_array($added_cc, $current_ccs)) {
if (empty($ccs[$added_cc])) {
$ccs[$added_cc] = $transaction->getDateCreated();
}
}
}
break;
}
}
foreach ($task->getProjectPHIDs() as $phid) {
$doc->addRelationship(
PhabricatorSearchRelationship::RELATIONSHIP_PROJECT,
$phid,
- 'PROJ',
+ PhabricatorPHIDConstants::PHID_TYPE_PROJ,
$task->getDateModified()); // Bogus.
}
if ($owner && $owner->getNewValue()) {
$doc->addRelationship(
PhabricatorSearchRelationship::RELATIONSHIP_OWNER,
$owner->getNewValue(),
- 'USER',
+ PhabricatorPHIDConstants::PHID_TYPE_USER,
$owner->getDateCreated());
} else {
$doc->addRelationship(
PhabricatorSearchRelationship::RELATIONSHIP_OWNER,
'PHID-!!!!-UP-FOR-GRABS',
- '!!!!',
+ PhabricatorPHIDConstants::PHID_TYPE_MAGIC,
$owner
? $owner->getDateCreated()
: $task->getDateCreated());
}
foreach ($touches as $touch => $time) {
$doc->addRelationship(
PhabricatorSearchRelationship::RELATIONSHIP_TOUCH,
$touch,
- 'USER',
+ PhabricatorPHIDConstants::PHID_TYPE_USER,
$time);
}
// We need to load handles here since non-users may subscribe (mailing
// lists, e.g.)
$handles = id(new PhabricatorObjectHandleData(array_keys($ccs)))
->loadHandles();
foreach ($ccs as $cc => $time) {
$doc->addRelationship(
PhabricatorSearchRelationship::RELATIONSHIP_SUBSCRIBER,
$handles[$cc]->getPHID(),
$handles[$cc]->getType(),
$time);
}
PhabricatorSearchDocument::reindexAbstractDocument($doc);
}
}
diff --git a/src/applications/search/index/indexer/maniphest/__init__.php b/src/applications/search/index/indexer/maniphest/__init__.php
index 62fe069f4e..a6e5eecdb5 100644
--- a/src/applications/search/index/indexer/maniphest/__init__.php
+++ b/src/applications/search/index/indexer/maniphest/__init__.php
@@ -1,22 +1,23 @@
<?php
/**
* This file is automatically generated. Lint this module to rebuild it.
* @generated
*/
phutil_require_module('phabricator', 'applications/maniphest/constants/status');
phutil_require_module('phabricator', 'applications/maniphest/constants/transactiontype');
phutil_require_module('phabricator', 'applications/maniphest/storage/transaction');
+phutil_require_module('phabricator', 'applications/phid/constants');
phutil_require_module('phabricator', 'applications/phid/handle/data');
phutil_require_module('phabricator', 'applications/search/constants/field');
phutil_require_module('phabricator', 'applications/search/constants/relationship');
phutil_require_module('phabricator', 'applications/search/index/abstractdocument');
phutil_require_module('phabricator', 'applications/search/index/indexer/base');
phutil_require_module('phabricator', 'applications/search/storage/document/document');
phutil_require_module('phutil', 'utils');
phutil_require_source('PhabricatorSearchManiphestIndexer.php');
diff --git a/src/storage/connection/base/AphrontDatabaseConnection.php b/src/storage/connection/base/AphrontDatabaseConnection.php
index 150f43b960..5d7fd27e27 100644
--- a/src/storage/connection/base/AphrontDatabaseConnection.php
+++ b/src/storage/connection/base/AphrontDatabaseConnection.php
@@ -1,231 +1,225 @@
<?php
/*
* Copyright 2011 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.
*/
/**
* @group storage
*/
abstract class AphrontDatabaseConnection {
private static $transactionStacks = array();
private static $transactionShutdownRegistered = false;
abstract public function getInsertID();
abstract public function getAffectedRows();
abstract public function selectAllResults();
abstract public function executeRawQuery($raw_query);
abstract protected function getTransactionKey();
abstract public function escapeString($string);
abstract public function escapeColumnName($string);
abstract public function escapeMultilineComment($string);
abstract public function escapeStringForLikeClause($string);
public function queryData($pattern/*, $arg, $arg, ... */) {
- if (false) {
- // Workaround for the HPHP workaround: ensure we include this module
- // since we really are using the function.
- queryfx($this, $pattern);
- }
-
$args = func_get_args();
array_unshift($args, $this);
- return hphp_workaround_call_user_func_array('queryfx_all', $args);
+ return call_user_func_array('queryfx_all', $args);
}
public function query($pattern/*, $arg, $arg, ... */) {
$args = func_get_args();
array_unshift($args, $this);
- return hphp_workaround_call_user_func_array('queryfx', $args);
+ return call_user_func_array('queryfx', $args);
}
// TODO: Probably need to reset these when we catch a connection exception
// in the transaction stack.
protected function &getLockLevels() {
static $levels = array();
$key = $this->getTransactionKey();
if (!isset($levels[$key])) {
$levels[$key] = array(
'read' => 0,
'write' => 0,
);
}
return $levels[$key];
}
public function isReadLocking() {
$levels = &$this->getLockLevels();
return ($levels['read'] > 0);
}
public function isWriteLocking() {
$levels = &$this->getLockLevels();
return ($levels['write'] > 0);
}
public function startReadLocking() {
$levels = &$this->getLockLevels();
++$levels['read'];
return $this;
}
public function startWriteLocking() {
$levels = &$this->getLockLevels();
++$levels['write'];
return $this;
}
public function stopReadLocking() {
$levels = &$this->getLockLevels();
if ($levels['read'] < 1) {
throw new Exception('Unable to stop read locking: not read locking.');
}
--$levels['read'];
return $this;
}
public function stopWriteLocking() {
$levels = &$this->getLockLevels();
if ($levels['write'] < 1) {
throw new Exception('Unable to stop read locking: not write locking.');
}
--$levels['write'];
return $this;
}
protected function &getTransactionStack($key) {
if (!self::$transactionShutdownRegistered) {
self::$transactionShutdownRegistered = true;
register_shutdown_function(
array(
'AphrontDatabaseConnection',
'shutdownTransactionStacks',
));
}
if (!isset(self::$transactionStacks[$key])) {
self::$transactionStacks[$key] = array();
}
return self::$transactionStacks[$key];
}
public static function shutdownTransactionStacks() {
foreach (self::$transactionStacks as $stack) {
if ($stack === false) {
continue;
}
$count = count($stack);
if ($count) {
throw new Exception(
'Script exited with '.$count.' open transactions! The '.
'transactions will be implicitly rolled back. Calls to '.
'openTransaction() should always be paired with a call to '.
'saveTransaction() or killTransaction(); you have an unpaired '.
'call somewhere.',
$count);
}
}
}
public function openTransaction() {
$key = $this->getTransactionKey();
$stack = &$this->getTransactionStack($key);
$new_transaction = !count($stack);
// TODO: At least in development, push context information instead of
// `true' so we can report (or, at least, guess) where unpaired
// transaction calls happened.
$stack[] = true;
end($stack);
$key = key($stack);
if ($new_transaction) {
$this->query('START TRANSACTION');
} else {
$this->query('SAVEPOINT '.$this->getSavepointName($key));
}
}
public function isInsideTransaction() {
$key = $this->getTransactionKey();
$stack = &$this->getTransactionStack($key);
return (bool)count($stack);
}
public function saveTransaction() {
$key = $this->getTransactionKey();
$stack = &$this->getTransactionStack($key);
if (!count($stack)) {
throw new Exception(
"No open transaction! Unable to save transaction, since there ".
"isn't one.");
}
array_pop($stack);
if (!count($stack)) {
$this->query('COMMIT');
}
}
public function saveTransactionUnless($cond) {
if ($cond) {
$this->killTransaction();
} else {
$this->saveTransaction();
}
}
public function saveTransactionIf($cond) {
$this->saveTransactionUnless(!$cond);
}
public function killTransaction() {
$key = $this->getTransactionKey();
$stack = &$this->getTransactionStack($key);
if (!count($stack)) {
throw new Exception(
"No open transaction! Unable to kill transaction, since there ".
"isn't one.");
}
$count = count($stack);
end($stack);
$key = key($stack);
array_pop($stack);
if (!count($stack)) {
$this->query('ROLLBACK');
} else {
$this->query(
'ROLLBACK TO SAVEPOINT '.$this->getSavepointName($key)
);
}
}
protected function getSavepointName($key) {
return 'LiskSavepoint_'.$key;
}
}
diff --git a/src/storage/queryfx/queryfx.php b/src/storage/queryfx/queryfx.php
index 91cb5bb376..6195d9c88e 100644
--- a/src/storage/queryfx/queryfx.php
+++ b/src/storage/queryfx/queryfx.php
@@ -1,70 +1,64 @@
<?php
/*
* Copyright 2011 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.
*/
/**
* @group storage
*/
function queryfx(AphrontDatabaseConnection $conn, $sql/*, ... */) {
- if (false) {
- // Workaround for the HPHP workaround: ensure we include this module
- // since we really are using the function.
- qsprintf($conn, $sql);
- }
-
$argv = func_get_args();
- $query = hphp_workaround_call_user_func_array('qsprintf', $argv);
+ $query = call_user_func_array('qsprintf', $argv);
$conn->executeRawQuery($query);
}
/**
* @group storage
*/
function vqueryfx($conn, $sql, $argv) {
array_unshift($argv, $conn, $sql);
- hphp_workaround_call_user_func_array('queryfx', $argv);
+ call_user_func_array('queryfx', $argv);
}
/**
* @group storage
*/
function queryfx_all($conn, $sql/*, ... */) {
$argv = func_get_args();
- hphp_workaround_call_user_func_array('queryfx', $argv);
+ call_user_func_array('queryfx', $argv);
return $conn->selectAllResults();
}
/**
* @group storage
*/
function queryfx_one($conn, $sql/*, ... */) {
$argv = func_get_args();
- $ret = hphp_workaround_call_user_func_array('queryfx_all', $argv);
+ $ret = call_user_func_array('queryfx_all', $argv);
if (count($ret) > 1) {
throw new AphrontQueryCountException(
'Query returned more than one row.');
} else if (count($ret)) {
return reset($ret);
}
return null;
}
function vqueryfx_all($conn, $sql, array $argv) {
array_unshift($argv, $conn, $sql);
- hphp_workaround_call_user_func_array('queryfx', $argv);
+ call_user_func_array('queryfx', $argv);
return $conn->selectAllResults();
}
diff --git a/webroot/index.php b/webroot/index.php
index 37e22d8f3f..9960f30c71 100644
--- a/webroot/index.php
+++ b/webroot/index.php
@@ -1,187 +1,178 @@
<?php
/*
* Copyright 2011 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.
*/
error_reporting(E_ALL | E_STRICT);
$env = getenv('PHABRICATOR_ENV'); // Apache
if (!$env) {
if (isset($_ENV['PHABRICATOR_ENV'])) {
$env = $_ENV['PHABRICATOR_ENV'];
}
}
if (!$env) {
phabricator_fatal_config_error(
"The 'PHABRICATOR_ENV' environmental variable is not defined. Modify ".
"your httpd.conf to include 'SetEnv PHABRICATOR_ENV <env>', where '<env>' ".
"is one of 'development', 'production', or a custom environment.");
}
if (!function_exists('mysql_connect')) {
phabricator_fatal_config_error(
"The PHP MySQL extension is not installed. This extension is required.");
}
if (!isset($_REQUEST['__path__'])) {
phabricator_fatal_config_error(
"__path__ is not set. Your rewrite rules are not configured correctly.");
}
require_once dirname(dirname(__FILE__)).'/conf/__init_conf__.php';
$conf = phabricator_read_config_file($env);
$conf['phabricator.env'] = $env;
setup_aphront_basics();
phutil_require_module('phabricator', 'infrastructure/env');
PhabricatorEnv::setEnvConfig($conf);
phutil_require_module('phabricator', 'aphront/console/plugin/xhprof/api');
DarkConsoleXHProfPluginAPI::hookProfiler();
phutil_require_module('phabricator', 'aphront/console/plugin/errorlog/api');
set_error_handler(array('DarkConsoleErrorLogPluginAPI', 'handleError'));
set_exception_handler(array('DarkConsoleErrorLogPluginAPI', 'handleException'));
foreach (PhabricatorEnv::getEnvConfig('load-libraries') as $library) {
phutil_load_library($library);
}
$host = $_SERVER['HTTP_HOST'];
$path = $_REQUEST['__path__'];
switch ($host) {
default:
$config_key = 'aphront.default-application-configuration-class';
$config_class = PhabricatorEnv::getEnvConfig($config_key);
PhutilSymbolLoader::loadClass($config_class);
$application = newv($config_class, array());
break;
}
$application->setHost($host);
$application->setPath($path);
$application->willBuildRequest();
$request = $application->buildRequest();
$application->setRequest($request);
list($controller, $uri_data) = $application->buildController();
try {
$controller->willBeginExecution();
$controller->willProcessRequest($uri_data);
$response = $controller->processRequest();
} catch (AphrontRedirectException $ex) {
$response = id(new AphrontRedirectResponse())
->setURI($ex->getURI());
} catch (Exception $ex) {
$response = $application->handleException($ex);
}
$response = $application->willSendResponse($response);
$response->setRequest($request);
$response_string = $response->buildResponseString();
$code = $response->getHTTPResponseCode();
if ($code != 200) {
header("HTTP/1.0 {$code}");
}
$headers = $response->getCacheHeaders();
$headers = array_merge($headers, $response->getHeaders());
foreach ($headers as $header) {
list($header, $value) = $header;
header("{$header}: {$value}");
}
// TODO: This shouldn't be possible in a production-configured environment.
if (isset($_REQUEST['__profile__']) &&
($_REQUEST['__profile__'] == 'all')) {
$profile = DarkConsoleXHProfPluginAPI::stopProfiler();
$profile =
'<div style="text-align: center; background: #ff00ff; padding: 1em;
font-size: 24px; font-weight: bold;">'.
'<a href="/xhprof/profile/'.$profile.'/">'.
'&gt;&gt;&gt; View Profile &lt;&lt;&lt;'.
'</a>'.
'</div>';
if (strpos($response_string, '<body>') !== false) {
$response_string = str_replace(
'<body>',
'<body>'.$profile,
$response_string);
} else {
echo $profile;
}
}
echo $response_string;
/**
* @group aphront
*/
function setup_aphront_basics() {
$aphront_root = dirname(dirname(__FILE__));
$libraries_root = dirname($aphront_root);
$root = null;
if (!empty($_SERVER['PHUTIL_LIBRARY_ROOT'])) {
$root = $_SERVER['PHUTIL_LIBRARY_ROOT'];
}
ini_set('include_path', $libraries_root.':'.ini_get('include_path'));
@include_once $root.'libphutil/src/__phutil_library_init__.php';
if (!@constant('__LIBPHUTIL__')) {
echo "ERROR: Unable to load libphutil. Update your PHP 'include_path' to ".
"include the parent directory of libphutil/.\n";
exit(1);
}
// Load Phabricator itself using the absolute path, so we never end up doing
// anything surprising (loading index.php and libraries from different
// directories).
phutil_load_library($aphront_root.'/src');
phutil_load_library('arcanist/src');
}
function __autoload($class_name) {
PhutilSymbolLoader::loadClass($class_name);
}
function phabricator_fatal_config_error($msg) {
header('Content-Type: text/plain', $replace = true, $http_error = 500);
$error = "CONFIG ERROR: ".$msg."\n";
error_log($error);
echo $error;
die();
}
-
-/**
- * Workaround for HipHop bug, see Facebook Task #503624.
- */
-function hphp_workaround_call_user_func_array($func, array $array) {
- $f = new ReflectionFunction($func);
- return $f->invokeArgs($array);
-}
-

File Metadata

Mime Type
text/x-diff
Expires
Wed, Dec 3, 1:22 PM (9 h, 33 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
433479
Default Alt Text
(175 KB)

Event Timeline