Page MenuHomestyx hydra

No OneTemporary

diff --git a/resources/sql/patches/049.projectowner.sql b/resources/sql/patches/049.projectowner.sql
new file mode 100644
index 0000000000..56af7474bf
--- /dev/null
+++ b/resources/sql/patches/049.projectowner.sql
@@ -0,0 +1,2 @@
+ALTER TABLE phabricator_project.project_affiliation
+ ADD isOwner bool NOT NULL;
\ No newline at end of file
diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php
index 5bddbe16c0..6d599a312f 100644
--- a/src/__phutil_library_map__.php
+++ b/src/__phutil_library_map__.php
@@ -1,1007 +1,1008 @@
<?php
/**
* This file is automatically generated. Use 'phutil_mapper.php' to rebuild it.
* @generated
*/
phutil_register_library_map(array(
'class' =>
array(
'Aphront304Response' => 'aphront/response/304',
'Aphront400Response' => 'aphront/response/400',
'Aphront404Response' => 'aphront/response/404',
'AphrontAjaxResponse' => 'aphront/response/ajax',
'AphrontApplicationConfiguration' => 'aphront/applicationconfiguration',
'AphrontAttachedFileView' => 'view/control/attachedfile',
'AphrontController' => 'aphront/controller',
'AphrontCrumbsView' => 'view/layout/crumbs',
'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',
'AphrontFilePreviewView' => 'view/layout/filepreview',
'AphrontFileResponse' => 'aphront/response/file',
'AphrontFormCheckboxControl' => 'view/form/control/checkbox',
'AphrontFormControl' => 'view/form/control/base',
'AphrontFormDividerControl' => 'view/form/control/divider',
'AphrontFormDragAndDropUploadControl' => 'view/form/control/draganddropupload',
'AphrontFormFileControl' => 'view/form/control/file',
'AphrontFormLayoutView' => 'view/form/layout',
'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',
'AphrontFormToggleButtonsControl' => 'view/form/control/togglebuttons',
'AphrontFormTokenizerControl' => 'view/form/control/tokenizer',
'AphrontFormView' => 'view/form/base',
'AphrontHeadsupActionListView' => 'view/layout/headsup/actionlist',
'AphrontHeadsupActionView' => 'view/layout/headsup/action',
'AphrontIsolatedDatabaseConnection' => 'storage/connection/isolated',
'AphrontIsolatedDatabaseConnectionTestCase' => 'storage/connection/isolated/__tests__',
'AphrontKeyboardShortcutsAvailableView' => 'view/widget/keyboardshortcuts',
'AphrontListFilterView' => 'view/layout/listfilter',
'AphrontMySQLDatabaseConnection' => 'storage/connection/mysql',
'AphrontNullView' => 'view/null',
'AphrontPageView' => 'view/page/base',
'AphrontPagerView' => 'view/control/pager',
'AphrontPanelView' => 'view/layout/panel',
'AphrontQueryAccessDeniedException' => 'storage/exception/accessdenied',
'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',
'AphrontReloadResponse' => 'aphront/response/reload',
'AphrontRequest' => 'aphront/request',
'AphrontRequestFailureView' => 'view/page/failure',
'AphrontResponse' => 'aphront/response/base',
'AphrontSideNavView' => 'view/layout/sidenav',
'AphrontTableView' => 'view/control/table',
'AphrontTokenizerTemplateView' => 'view/control/tokenizer',
'AphrontTypeaheadTemplateView' => 'view/control/typeahead',
'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_getcertificate_Method' => 'applications/conduit/method/conduit/getcertificate',
'ConduitAPI_conduit_ping_Method' => 'applications/conduit/method/conduit/ping',
'ConduitAPI_daemon_launched_Method' => 'applications/conduit/method/daemon/launched',
'ConduitAPI_daemon_log_Method' => 'applications/conduit/method/daemon/log',
'ConduitAPI_differential_creatediff_Method' => 'applications/conduit/method/differential/creatediff',
'ConduitAPI_differential_createrevision_Method' => 'applications/conduit/method/differential/createrevision',
'ConduitAPI_differential_find_Method' => 'applications/conduit/method/differential/find',
'ConduitAPI_differential_getalldiffs_Method' => 'applications/conduit/method/differential/getalldiffs',
'ConduitAPI_differential_getcommitmessage_Method' => 'applications/conduit/method/differential/getcommitmessage',
'ConduitAPI_differential_getcommitpaths_Method' => 'applications/conduit/method/differential/getcommitpaths',
'ConduitAPI_differential_getdiff_Method' => 'applications/conduit/method/differential/getdiff',
'ConduitAPI_differential_getrevision_Method' => 'applications/conduit/method/differential/getrevision',
'ConduitAPI_differential_getrevisionfeedback_Method' => 'applications/conduit/method/differential/getrevisionfeedback',
'ConduitAPI_differential_markcommitted_Method' => 'applications/conduit/method/differential/markcommitted',
'ConduitAPI_differential_parsecommitmessage_Method' => 'applications/conduit/method/differential/parsecommitmessage',
'ConduitAPI_differential_setdiffproperty_Method' => 'applications/conduit/method/differential/setdiffproperty',
'ConduitAPI_differential_updaterevision_Method' => 'applications/conduit/method/differential/updaterevision',
'ConduitAPI_differential_updatetaskrevisionassoc_Method' => 'applications/conduit/method/differential/updatetaskrevisionassoc',
'ConduitAPI_differential_updateunitresults_Method' => 'applications/conduit/method/differential/updateunitresults',
'ConduitAPI_diffusion_getcommits_Method' => 'applications/conduit/method/diffusion/getcommits',
'ConduitAPI_diffusion_getrecentcommitsbypath_Method' => 'applications/conduit/method/diffusion/getrecentcommitsbypath',
'ConduitAPI_file_download_Method' => 'applications/conduit/method/file/download',
'ConduitAPI_file_upload_Method' => 'applications/conduit/method/file/upload',
'ConduitAPI_maniphest_info_Method' => 'applications/conduit/method/maniphest/info',
'ConduitAPI_paste_info_Method' => 'applications/conduit/method/paste/info',
'ConduitAPI_path_getowners_Method' => 'applications/conduit/method/path/getowners',
'ConduitAPI_user_find_Method' => 'applications/conduit/method/user/find',
'ConduitAPI_user_whoami_Method' => 'applications/conduit/method/user/whoami',
'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',
'DarkConsoleXHProfPlugin' => 'aphront/console/plugin/xhprof',
'DarkConsoleXHProfPluginAPI' => 'aphront/console/plugin/xhprof/api',
'DatabaseConfigurationProvider' => 'applications/base/storage/configuration',
'DifferentialAction' => 'applications/differential/constants/action',
'DifferentialAddCommentView' => 'applications/differential/view/addcomment',
'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',
'DifferentialExceptionMail' => 'applications/differential/mail/exception',
'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',
'DifferentialPrimaryPaneView' => 'applications/differential/view/primarypane',
'DifferentialReplyHandler' => 'applications/differential/replyhandler',
'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',
'DifferentialRevisionDetailRenderer' => 'applications/differential/controller/customrenderer',
'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',
'DifferentialTasksAttacher' => 'applications/differential/tasks',
'DifferentialUnitStatus' => 'applications/differential/constants/unitstatus',
'DifferentialUnitTestResult' => 'applications/differential/constants/unittestresult',
'DifferentialViewTime' => 'applications/differential/storage/viewtime',
'DiffusionBranchInformation' => 'applications/diffusion/data/branch',
'DiffusionBranchQuery' => 'applications/diffusion/query/branch/base',
'DiffusionBranchTableView' => 'applications/diffusion/view/branchtable',
'DiffusionBrowseController' => 'applications/diffusion/controller/browse',
'DiffusionBrowseFileController' => 'applications/diffusion/controller/file',
'DiffusionBrowseQuery' => 'applications/diffusion/query/browse/base',
'DiffusionBrowseTableView' => 'applications/diffusion/view/browsetable',
'DiffusionChangeController' => 'applications/diffusion/controller/change',
'DiffusionCommitChangeTableView' => 'applications/diffusion/view/commitchangetable',
'DiffusionCommitController' => 'applications/diffusion/controller/commit',
'DiffusionController' => 'applications/diffusion/controller/base',
'DiffusionDiffController' => 'applications/diffusion/controller/diff',
'DiffusionDiffQuery' => 'applications/diffusion/query/diff/base',
'DiffusionFileContent' => 'applications/diffusion/data/filecontent',
'DiffusionFileContentQuery' => 'applications/diffusion/query/filecontent/base',
'DiffusionGitBranchQuery' => 'applications/diffusion/query/branch/git',
'DiffusionGitBrowseQuery' => 'applications/diffusion/query/browse/git',
'DiffusionGitDiffQuery' => 'applications/diffusion/query/diff/git',
'DiffusionGitFileContentQuery' => 'applications/diffusion/query/filecontent/git',
'DiffusionGitHistoryQuery' => 'applications/diffusion/query/history/git',
'DiffusionGitLastModifiedQuery' => 'applications/diffusion/query/lastmodified/git',
'DiffusionGitPathIDQuery' => 'applications/diffusion/query/pathid/base',
'DiffusionGitRequest' => 'applications/diffusion/request/git',
'DiffusionHistoryController' => 'applications/diffusion/controller/history',
'DiffusionHistoryQuery' => 'applications/diffusion/query/history/base',
'DiffusionHistoryTableView' => 'applications/diffusion/view/historytable',
'DiffusionHomeController' => 'applications/diffusion/controller/home',
'DiffusionLastModifiedController' => 'applications/diffusion/controller/lastmodified',
'DiffusionLastModifiedQuery' => 'applications/diffusion/query/lastmodified/base',
'DiffusionPathChange' => 'applications/diffusion/data/pathchange',
'DiffusionPathChangeQuery' => 'applications/diffusion/query/pathchange/base',
'DiffusionPathCompleteController' => 'applications/diffusion/controller/pathcomplete',
'DiffusionPathValidateController' => 'applications/diffusion/controller/pathvalidate',
'DiffusionRepositoryController' => 'applications/diffusion/controller/repository',
'DiffusionRepositoryPath' => 'applications/diffusion/data/repositorypath',
'DiffusionRequest' => 'applications/diffusion/request/base',
'DiffusionSvnBrowseQuery' => 'applications/diffusion/query/browse/svn',
'DiffusionSvnDiffQuery' => 'applications/diffusion/query/diff/svn',
'DiffusionSvnFileContentQuery' => 'applications/diffusion/query/filecontent/svn',
'DiffusionSvnHistoryQuery' => 'applications/diffusion/query/history/svn',
'DiffusionSvnLastModifiedQuery' => 'applications/diffusion/query/lastmodified/svn',
'DiffusionSvnRequest' => 'applications/diffusion/request/svn',
'DiffusionView' => 'applications/diffusion/view/base',
'HeraldAction' => 'applications/herald/storage/action',
'HeraldActionConfig' => 'applications/herald/config/action',
'HeraldApplyTranscript' => 'applications/herald/storage/transcript/apply',
'HeraldCommitAdapter' => 'applications/herald/adapter/commit',
'HeraldCondition' => 'applications/herald/storage/condition',
'HeraldConditionConfig' => 'applications/herald/config/condition',
'HeraldConditionTranscript' => 'applications/herald/storage/transcript/condition',
'HeraldContentTypeConfig' => 'applications/herald/config/contenttype',
'HeraldController' => 'applications/herald/controller/base',
'HeraldDAO' => 'applications/herald/storage/base',
'HeraldDeleteController' => 'applications/herald/controller/delete',
'HeraldDifferentialRevisionAdapter' => 'applications/herald/adapter/differential',
'HeraldDryRunAdapter' => 'applications/herald/adapter/dryrun',
'HeraldEffect' => 'applications/herald/engine/effect',
'HeraldEngine' => 'applications/herald/engine/engine',
'HeraldFieldConfig' => 'applications/herald/config/field',
'HeraldHomeController' => 'applications/herald/controller/home',
'HeraldInvalidConditionException' => 'applications/herald/engine/engine/exception',
'HeraldInvalidFieldException' => 'applications/herald/engine/engine/exception',
'HeraldNewController' => 'applications/herald/controller/new',
'HeraldObjectAdapter' => 'applications/herald/adapter/base',
'HeraldObjectTranscript' => 'applications/herald/storage/transcript/object',
'HeraldRecursiveConditionsException' => 'applications/herald/engine/engine/exception',
'HeraldRepetitionPolicyConfig' => 'applications/herald/config/repetitionpolicy',
'HeraldRule' => 'applications/herald/storage/rule',
'HeraldRuleController' => 'applications/herald/controller/rule',
'HeraldRuleTranscript' => 'applications/herald/storage/transcript/rule',
'HeraldTestConsoleController' => 'applications/herald/controller/test',
'HeraldTranscript' => 'applications/herald/storage/transcript/base',
'HeraldTranscriptController' => 'applications/herald/controller/transcript',
'HeraldTranscriptListController' => 'applications/herald/controller/transcriptlist',
'HeraldValueTypeConfig' => 'applications/herald/config/valuetype',
'Javelin' => 'infrastructure/javelin/api',
'LiskDAO' => 'storage/lisk/dao',
'LiskIsolationTestCase' => 'storage/lisk/dao/__tests__',
'LiskIsolationTestDAO' => 'storage/lisk/dao/__tests__',
'LiskIsolationTestDAOException' => 'storage/lisk/dao/__tests__',
'ManiphestController' => 'applications/maniphest/controller/base',
'ManiphestDAO' => 'applications/maniphest/storage/base',
'ManiphestReplyHandler' => 'applications/maniphest/replyhandler',
'ManiphestTask' => 'applications/maniphest/storage/task',
'ManiphestTaskDescriptionChangeController' => 'applications/maniphest/controller/descriptionchange',
'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',
'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',
'ManiphestTransactionPreviewController' => 'applications/maniphest/controller/transactionpreview',
'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',
'PhabricatorConduitCertificateToken' => 'applications/conduit/storage/token',
'PhabricatorConduitConnectionLog' => 'applications/conduit/storage/connectionlog',
'PhabricatorConduitConsoleController' => 'applications/conduit/controller/console',
'PhabricatorConduitController' => 'applications/conduit/controller/base',
'PhabricatorConduitDAO' => 'applications/conduit/storage/base',
'PhabricatorConduitLogController' => 'applications/conduit/controller/log',
'PhabricatorConduitMethodCallLog' => 'applications/conduit/storage/methodcalllog',
'PhabricatorConduitTokenController' => 'applications/conduit/controller/token',
'PhabricatorController' => 'applications/base/controller/base',
'PhabricatorCountdownController' => 'applications/countdown/controller/base',
'PhabricatorCountdownDAO' => 'applications/countdown/storage/base',
'PhabricatorCountdownDeleteController' => 'applications/countdown/controller/delete',
'PhabricatorCountdownEditController' => 'applications/countdown/controller/edit',
'PhabricatorCountdownListController' => 'applications/countdown/controller/list',
'PhabricatorCountdownViewController' => 'applications/countdown/controller/view',
'PhabricatorDaemon' => 'infrastructure/daemon/base',
'PhabricatorDaemonCombinedLogController' => 'applications/daemon/controller/combined',
'PhabricatorDaemonConsoleController' => 'applications/daemon/controller/console',
'PhabricatorDaemonControl' => 'infrastructure/daemon/control',
'PhabricatorDaemonController' => 'applications/daemon/controller/base',
'PhabricatorDaemonDAO' => 'infrastructure/daemon/storage/base',
'PhabricatorDaemonLog' => 'infrastructure/daemon/storage/log',
'PhabricatorDaemonLogEvent' => 'infrastructure/daemon/storage/event',
'PhabricatorDaemonLogEventsView' => 'applications/daemon/view/daemonlogevents',
'PhabricatorDaemonLogListController' => 'applications/daemon/controller/loglist',
'PhabricatorDaemonLogListView' => 'applications/daemon/view/daemonloglist',
'PhabricatorDaemonLogViewController' => 'applications/daemon/controller/logview',
'PhabricatorDaemonReference' => 'infrastructure/daemon/control/reference',
'PhabricatorDaemonTimelineConsoleController' => 'applications/daemon/controller/timeline',
'PhabricatorDaemonTimelineEventController' => 'applications/daemon/controller/timelineevent',
'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',
'PhabricatorDisabledUserController' => 'applications/auth/controller/disabled',
'PhabricatorDraft' => 'applications/draft/storage/draft',
'PhabricatorDraftDAO' => 'applications/draft/storage/base',
'PhabricatorEditPreferencesController' => 'applications/preferences/controller/edit',
'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',
'PhabricatorFileDropUploadController' => 'applications/files/controller/dropupload',
'PhabricatorFileImageMacro' => 'applications/files/storage/imagemacro',
'PhabricatorFileListController' => 'applications/files/controller/list',
'PhabricatorFileMacroDeleteController' => 'applications/files/controller/macrodelete',
'PhabricatorFileMacroEditController' => 'applications/files/controller/macroedit',
'PhabricatorFileMacroListController' => 'applications/files/controller/macrolist',
'PhabricatorFileProxyController' => 'applications/files/controller/proxy',
'PhabricatorFileProxyImage' => 'applications/files/storage/proxyimage',
'PhabricatorFileStorageBlob' => 'applications/files/storage/storageblob',
'PhabricatorFileTransformController' => 'applications/files/controller/transform',
'PhabricatorFileURI' => 'applications/files/uri',
'PhabricatorFileUploadController' => 'applications/files/controller/upload',
'PhabricatorFileViewController' => 'applications/files/controller/view',
'PhabricatorGoodForNothingWorker' => 'infrastructure/daemon/workers/worker/goodfornothing',
'PhabricatorHandleObjectSelectorDataView' => 'applications/phid/handle/view/selector',
'PhabricatorHelpController' => 'applications/help/controller/base',
'PhabricatorHelpKeyboardShortcutController' => 'applications/help/controller/keyboardshortcut',
'PhabricatorIRCBot' => 'infrastructure/daemon/irc/bot',
'PhabricatorIRCHandler' => 'infrastructure/daemon/irc/handler/base',
'PhabricatorIRCMessage' => 'infrastructure/daemon/irc/message',
'PhabricatorIRCObjectNameHandler' => 'infrastructure/daemon/irc/handler/objectname',
'PhabricatorIRCProtocolHandler' => 'infrastructure/daemon/irc/handler/protocol',
+ 'PhabricatorImageTransformer' => 'applications/files/transform',
'PhabricatorJavelinLinter' => 'infrastructure/lint/linter/javelin',
'PhabricatorLintEngine' => 'infrastructure/lint/engine',
'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',
'PhabricatorMailImplementationSendGridAdapter' => 'applications/metamta/adapter/sendgrid',
'PhabricatorMailImplementationTestAdapter' => 'applications/metamta/adapter/test',
'PhabricatorMailReplyHandler' => 'applications/metamta/replyhandler/base',
'PhabricatorMetaMTAController' => 'applications/metamta/controller/base',
'PhabricatorMetaMTADAO' => 'applications/metamta/storage/base',
'PhabricatorMetaMTADaemon' => 'applications/metamta/daemon/mta',
'PhabricatorMetaMTAEmailBodyParser' => 'applications/metamta/parser',
'PhabricatorMetaMTAEmailBodyParserTestCase' => 'applications/metamta/parser/__tests__',
'PhabricatorMetaMTAListController' => 'applications/metamta/controller/list',
'PhabricatorMetaMTAMail' => 'applications/metamta/storage/mail',
'PhabricatorMetaMTAMailTestCase' => 'applications/metamta/storage/mail/__tests__',
'PhabricatorMetaMTAMailingList' => 'applications/metamta/storage/mailinglist',
'PhabricatorMetaMTAMailingListEditController' => 'applications/metamta/controller/mailinglistedit',
'PhabricatorMetaMTAMailingListsController' => 'applications/metamta/controller/mailinglists',
'PhabricatorMetaMTAReceiveController' => 'applications/metamta/controller/receive',
'PhabricatorMetaMTAReceivedListController' => 'applications/metamta/controller/receivedlist',
'PhabricatorMetaMTAReceivedMail' => 'applications/metamta/storage/receivedmail',
'PhabricatorMetaMTASendController' => 'applications/metamta/controller/send',
'PhabricatorMetaMTASendGridReceiveController' => 'applications/metamta/controller/sendgridreceive',
'PhabricatorMetaMTAViewController' => 'applications/metamta/controller/view',
'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',
'PhabricatorOwnersController' => 'applications/owners/controller/base',
'PhabricatorOwnersDAO' => 'applications/owners/storage/base',
'PhabricatorOwnersDeleteController' => 'applications/owners/controller/delete',
'PhabricatorOwnersDetailController' => 'applications/owners/controller/detail',
'PhabricatorOwnersEditController' => 'applications/owners/controller/edit',
'PhabricatorOwnersListController' => 'applications/owners/controller/list',
'PhabricatorOwnersOwner' => 'applications/owners/storage/owner',
'PhabricatorOwnersPackage' => 'applications/owners/storage/package',
'PhabricatorOwnersPath' => 'applications/owners/storage/path',
'PhabricatorPHID' => 'applications/phid/storage/phid',
'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',
'PhabricatorPaste' => 'applications/paste/storage/paste',
'PhabricatorPasteController' => 'applications/paste/controller/base',
'PhabricatorPasteCreateController' => 'applications/paste/controller/create',
'PhabricatorPasteDAO' => 'applications/paste/storage/base',
'PhabricatorPasteListController' => 'applications/paste/controller/list',
'PhabricatorPasteViewController' => 'applications/paste/controller/view',
'PhabricatorPeopleController' => 'applications/people/controller/base',
'PhabricatorPeopleEditController' => 'applications/people/controller/edit',
'PhabricatorPeopleListController' => 'applications/people/controller/list',
'PhabricatorPeopleLogsController' => 'applications/people/controller/logs',
'PhabricatorPeopleProfileController' => 'applications/people/controller/profile',
'PhabricatorPeopleProfileEditController' => 'applications/people/controller/profileedit',
'PhabricatorPreferencesController' => 'applications/preferences/controller/base',
'PhabricatorProfileView' => 'view/layout/profile',
'PhabricatorProject' => 'applications/project/storage/project',
'PhabricatorProjectAffiliation' => 'applications/project/storage/affiliation',
'PhabricatorProjectAffiliationEditController' => 'applications/project/controller/editaffiliation',
'PhabricatorProjectController' => 'applications/project/controller/base',
+ 'PhabricatorProjectCreateController' => 'applications/project/controller/create',
'PhabricatorProjectDAO' => 'applications/project/storage/base',
'PhabricatorProjectListController' => 'applications/project/controller/list',
'PhabricatorProjectProfile' => 'applications/project/storage/profile',
'PhabricatorProjectProfileController' => 'applications/project/controller/profile',
'PhabricatorProjectProfileEditController' => 'applications/project/controller/profileedit',
- 'PhabricatorProjectQuickCreateController' => 'applications/project/controller/quickcreate',
'PhabricatorProjectStatus' => 'applications/project/constants/status',
'PhabricatorProjectTransactionSearch' => 'applications/project/transactions/search',
'PhabricatorRedirectController' => 'applications/base/controller/redirect',
'PhabricatorRemarkupRuleDifferential' => 'infrastructure/markup/remarkup/markuprule/differential',
'PhabricatorRemarkupRuleDiffusion' => 'infrastructure/markup/remarkup/markuprule/diffusion',
'PhabricatorRemarkupRuleImageMacro' => 'infrastructure/markup/remarkup/markuprule/imagemacro',
'PhabricatorRemarkupRuleManiphest' => 'infrastructure/markup/remarkup/markuprule/maniphest',
'PhabricatorRemarkupRuleMention' => 'infrastructure/markup/remarkup/markuprule/mention',
'PhabricatorRemarkupRuleObjectName' => 'infrastructure/markup/remarkup/markuprule/objectname',
'PhabricatorRemarkupRuleProxyImage' => 'infrastructure/markup/remarkup/markuprule/proxyimage',
'PhabricatorRemarkupRuleYoutube' => 'infrastructure/markup/remarkup/markuprule/youtube',
'PhabricatorRepository' => 'applications/repository/storage/repository',
'PhabricatorRepositoryArcanistProject' => 'applications/repository/storage/arcanistproject',
'PhabricatorRepositoryArcanistProjectEditController' => 'applications/repository/controller/arcansistprojectedit',
'PhabricatorRepositoryCommit' => 'applications/repository/storage/commit',
'PhabricatorRepositoryCommitChangeParserWorker' => 'applications/repository/worker/commitchangeparser/base',
'PhabricatorRepositoryCommitData' => 'applications/repository/storage/commitdata',
'PhabricatorRepositoryCommitDiscoveryDaemon' => 'applications/repository/daemon/commitdiscovery/base',
'PhabricatorRepositoryCommitHeraldWorker' => 'applications/repository/worker/herald',
'PhabricatorRepositoryCommitMessageDetailParser' => 'applications/repository/parser/base',
'PhabricatorRepositoryCommitMessageParserWorker' => 'applications/repository/worker/commitmessageparser/base',
'PhabricatorRepositoryCommitParserWorker' => 'applications/repository/worker/base',
'PhabricatorRepositoryCommitTaskDaemon' => 'applications/repository/daemon/committask',
'PhabricatorRepositoryController' => 'applications/repository/controller/base',
'PhabricatorRepositoryCreateController' => 'applications/repository/controller/create',
'PhabricatorRepositoryDAO' => 'applications/repository/storage/base',
'PhabricatorRepositoryDaemon' => 'applications/repository/daemon/base',
'PhabricatorRepositoryDefaultCommitMessageDetailParser' => 'applications/repository/parser/default',
'PhabricatorRepositoryDeleteController' => 'applications/repository/controller/delete',
'PhabricatorRepositoryEditController' => 'applications/repository/controller/edit',
'PhabricatorRepositoryGitCommitChangeParserWorker' => 'applications/repository/worker/commitchangeparser/git',
'PhabricatorRepositoryGitCommitDiscoveryDaemon' => 'applications/repository/daemon/commitdiscovery/git',
'PhabricatorRepositoryGitCommitMessageParserWorker' => 'applications/repository/worker/commitmessageparser/git',
'PhabricatorRepositoryGitFetchDaemon' => 'applications/repository/daemon/gitfetch',
'PhabricatorRepositoryGitHubNotification' => 'applications/repository/storage/githubnotification',
'PhabricatorRepositoryGitHubPostReceiveController' => 'applications/repository/controller/github-post-receive',
'PhabricatorRepositoryListController' => 'applications/repository/controller/list',
'PhabricatorRepositoryShortcut' => 'applications/repository/storage/shortcut',
'PhabricatorRepositorySvnCommitChangeParserWorker' => 'applications/repository/worker/commitchangeparser/svn',
'PhabricatorRepositorySvnCommitDiscoveryDaemon' => 'applications/repository/daemon/commitdiscovery/svn',
'PhabricatorRepositorySvnCommitMessageParserWorker' => 'applications/repository/worker/commitmessageparser/svn',
'PhabricatorRepositoryType' => 'applications/repository/constants/repositorytype',
'PhabricatorSQLPatchList' => 'infrastructure/setup/sql',
'PhabricatorSearchAbstractDocument' => 'applications/search/index/abstractdocument',
'PhabricatorSearchAttachController' => 'applications/search/controller/attach',
'PhabricatorSearchBaseController' => 'applications/search/controller/base',
'PhabricatorSearchCommitIndexer' => 'applications/search/index/indexer/repository',
'PhabricatorSearchController' => 'applications/search/controller/search',
'PhabricatorSearchDAO' => 'applications/search/storage/base',
'PhabricatorSearchDifferentialIndexer' => 'applications/search/index/indexer/differential',
'PhabricatorSearchDocument' => 'applications/search/storage/document/document',
'PhabricatorSearchDocumentField' => 'applications/search/storage/document/field',
'PhabricatorSearchDocumentIndexer' => 'applications/search/index/indexer/base',
'PhabricatorSearchDocumentRelationship' => 'applications/search/storage/document/relationship',
'PhabricatorSearchExecutor' => 'applications/search/execute/base',
'PhabricatorSearchField' => 'applications/search/constants/field',
'PhabricatorSearchIndexController' => 'applications/search/controller/index',
'PhabricatorSearchManiphestIndexer' => 'applications/search/index/indexer/maniphest',
'PhabricatorSearchMySQLExecutor' => 'applications/search/execute/mysql',
'PhabricatorSearchQuery' => 'applications/search/storage/query',
'PhabricatorSearchRelationship' => 'applications/search/constants/relationship',
'PhabricatorSearchSelectController' => 'applications/search/controller/select',
'PhabricatorSearchUserIndexer' => 'applications/search/index/indexer/user',
'PhabricatorSetup' => 'infrastructure/setup',
'PhabricatorStandardPageView' => 'view/page/standard',
'PhabricatorStatusController' => 'applications/status/base',
'PhabricatorTaskmasterDaemon' => 'infrastructure/daemon/workers/taskmaster',
'PhabricatorTestCase' => 'infrastructure/testing/testcase',
'PhabricatorTimelineCursor' => 'infrastructure/daemon/timeline/storage/cursor',
'PhabricatorTimelineDAO' => 'infrastructure/daemon/timeline/storage/base',
'PhabricatorTimelineEvent' => 'infrastructure/daemon/timeline/storage/event',
'PhabricatorTimelineEventData' => 'infrastructure/daemon/timeline/storage/eventdata',
'PhabricatorTimelineIterator' => 'infrastructure/daemon/timeline/cursor/iterator',
'PhabricatorTimer' => 'applications/countdown/storage/timer',
'PhabricatorTransformedFile' => 'applications/files/storage/transformed',
'PhabricatorTypeaheadCommonDatasourceController' => 'applications/typeahead/controller/common',
'PhabricatorTypeaheadDatasourceController' => 'applications/typeahead/controller/base',
'PhabricatorUIExample' => 'applications/uiexample/examples/base',
'PhabricatorUIExampleController' => 'applications/uiexample/controller/base',
'PhabricatorUIExampleRenderController' => 'applications/uiexample/controller/render',
'PhabricatorUIListFilterExample' => 'applications/uiexample/examples/listfilter',
'PhabricatorUIPagerExample' => 'applications/uiexample/examples/pager',
'PhabricatorUser' => 'applications/people/storage/user',
'PhabricatorUserDAO' => 'applications/people/storage/base',
'PhabricatorUserLog' => 'applications/people/storage/log',
'PhabricatorUserOAuthInfo' => 'applications/people/storage/useroauthinfo',
'PhabricatorUserPreferences' => 'applications/people/storage/preferences',
'PhabricatorUserProfile' => 'applications/people/storage/profile',
'PhabricatorUserSettingsController' => 'applications/people/controller/settings',
'PhabricatorWorker' => 'infrastructure/daemon/workers/worker',
'PhabricatorWorkerDAO' => 'infrastructure/daemon/workers/storage/base',
'PhabricatorWorkerTask' => 'infrastructure/daemon/workers/storage/task',
'PhabricatorWorkerTaskData' => 'infrastructure/daemon/workers/storage/taskdata',
'PhabricatorWorkerTaskDetailController' => 'applications/daemon/controller/workertaskdetail',
'PhabricatorXHPASTViewController' => 'applications/xhpastview/controller/base',
'PhabricatorXHPASTViewDAO' => 'applications/xhpastview/storage/base',
'PhabricatorXHPASTViewFrameController' => 'applications/xhpastview/controller/viewframe',
'PhabricatorXHPASTViewFramesetController' => 'applications/xhpastview/controller/viewframeset',
'PhabricatorXHPASTViewInputController' => 'applications/xhpastview/controller/viewinput',
'PhabricatorXHPASTViewPanelController' => 'applications/xhpastview/controller/viewpanel',
'PhabricatorXHPASTViewParseTree' => 'applications/xhpastview/storage/parsetree',
'PhabricatorXHPASTViewRunController' => 'applications/xhpastview/controller/run',
'PhabricatorXHPASTViewStreamController' => 'applications/xhpastview/controller/viewstream',
'PhabricatorXHPASTViewTreeController' => 'applications/xhpastview/controller/viewtree',
'PhabricatorXHProfController' => 'applications/xhprof/controller/base',
'PhabricatorXHProfProfileController' => 'applications/xhprof/controller/profile',
'PhabricatorXHProfProfileSymbolView' => 'applications/xhprof/view/symbol',
'PhabricatorXHProfProfileTopLevelView' => 'applications/xhprof/view/toplevel',
),
'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_date' => 'view/utils',
'phabricator_datetime' => 'view/utils',
'phabricator_format_relative_time' => 'view/utils',
'phabricator_format_timestamp' => 'view/utils',
'phabricator_format_units_generic' => 'view/utils',
'phabricator_render_form' => 'infrastructure/javelin/markup',
'phabricator_time' => 'view/utils',
'qsprintf' => 'storage/qsprintf',
'queryfx' => 'storage/queryfx',
'queryfx_all' => 'storage/queryfx',
'queryfx_one' => 'storage/queryfx',
'require_celerity_resource' => 'infrastructure/celerity/api',
'vqsprintf' => 'storage/qsprintf',
'vqueryfx' => 'storage/queryfx',
'vqueryfx_all' => 'storage/queryfx',
'xsprintf_query' => 'storage/qsprintf',
),
'requires_class' =>
array(
'Aphront304Response' => 'AphrontResponse',
'Aphront400Response' => 'AphrontResponse',
'Aphront404Response' => 'AphrontResponse',
'AphrontAjaxResponse' => 'AphrontResponse',
'AphrontAttachedFileView' => 'AphrontView',
'AphrontCrumbsView' => 'AphrontView',
'AphrontDefaultApplicationConfiguration' => 'AphrontApplicationConfiguration',
'AphrontDefaultApplicationController' => 'AphrontController',
'AphrontDialogResponse' => 'AphrontResponse',
'AphrontDialogView' => 'AphrontView',
'AphrontErrorView' => 'AphrontView',
'AphrontFilePreviewView' => 'AphrontView',
'AphrontFileResponse' => 'AphrontResponse',
'AphrontFormCheckboxControl' => 'AphrontFormControl',
'AphrontFormControl' => 'AphrontView',
'AphrontFormDividerControl' => 'AphrontFormControl',
'AphrontFormDragAndDropUploadControl' => 'AphrontFormControl',
'AphrontFormFileControl' => 'AphrontFormControl',
'AphrontFormLayoutView' => 'AphrontView',
'AphrontFormMarkupControl' => 'AphrontFormControl',
'AphrontFormPasswordControl' => 'AphrontFormControl',
'AphrontFormRecaptchaControl' => 'AphrontFormControl',
'AphrontFormSelectControl' => 'AphrontFormControl',
'AphrontFormStaticControl' => 'AphrontFormControl',
'AphrontFormSubmitControl' => 'AphrontFormControl',
'AphrontFormTextAreaControl' => 'AphrontFormControl',
'AphrontFormTextControl' => 'AphrontFormControl',
'AphrontFormToggleButtonsControl' => 'AphrontFormControl',
'AphrontFormTokenizerControl' => 'AphrontFormControl',
'AphrontFormView' => 'AphrontView',
'AphrontHeadsupActionListView' => 'AphrontView',
'AphrontHeadsupActionView' => 'AphrontView',
'AphrontIsolatedDatabaseConnection' => 'AphrontDatabaseConnection',
'AphrontIsolatedDatabaseConnectionTestCase' => 'PhabricatorTestCase',
'AphrontKeyboardShortcutsAvailableView' => 'AphrontView',
'AphrontListFilterView' => 'AphrontView',
'AphrontMySQLDatabaseConnection' => 'AphrontDatabaseConnection',
'AphrontNullView' => 'AphrontView',
'AphrontPageView' => 'AphrontView',
'AphrontPagerView' => 'AphrontView',
'AphrontPanelView' => 'AphrontView',
'AphrontQueryAccessDeniedException' => 'AphrontQueryRecoverableException',
'AphrontQueryConnectionException' => 'AphrontQueryException',
'AphrontQueryConnectionLostException' => 'AphrontQueryRecoverableException',
'AphrontQueryCountException' => 'AphrontQueryException',
'AphrontQueryDuplicateKeyException' => 'AphrontQueryException',
'AphrontQueryObjectMissingException' => 'AphrontQueryException',
'AphrontQueryParameterException' => 'AphrontQueryException',
'AphrontQueryRecoverableException' => 'AphrontQueryException',
'AphrontRedirectException' => 'AphrontException',
'AphrontRedirectResponse' => 'AphrontResponse',
'AphrontReloadResponse' => 'AphrontRedirectResponse',
'AphrontRequestFailureView' => 'AphrontView',
'AphrontSideNavView' => 'AphrontView',
'AphrontTableView' => 'AphrontView',
'AphrontTokenizerTemplateView' => 'AphrontView',
'AphrontTypeaheadTemplateView' => 'AphrontView',
'AphrontWebpageResponse' => 'AphrontResponse',
'CelerityResourceController' => 'AphrontController',
'ConduitAPI_conduit_connect_Method' => 'ConduitAPIMethod',
'ConduitAPI_conduit_getcertificate_Method' => 'ConduitAPIMethod',
'ConduitAPI_conduit_ping_Method' => 'ConduitAPIMethod',
'ConduitAPI_daemon_launched_Method' => 'ConduitAPIMethod',
'ConduitAPI_daemon_log_Method' => 'ConduitAPIMethod',
'ConduitAPI_differential_creatediff_Method' => 'ConduitAPIMethod',
'ConduitAPI_differential_createrevision_Method' => 'ConduitAPIMethod',
'ConduitAPI_differential_find_Method' => 'ConduitAPIMethod',
'ConduitAPI_differential_getalldiffs_Method' => 'ConduitAPIMethod',
'ConduitAPI_differential_getcommitmessage_Method' => 'ConduitAPIMethod',
'ConduitAPI_differential_getcommitpaths_Method' => 'ConduitAPIMethod',
'ConduitAPI_differential_getdiff_Method' => 'ConduitAPIMethod',
'ConduitAPI_differential_getrevision_Method' => 'ConduitAPIMethod',
'ConduitAPI_differential_getrevisionfeedback_Method' => 'ConduitAPIMethod',
'ConduitAPI_differential_markcommitted_Method' => 'ConduitAPIMethod',
'ConduitAPI_differential_parsecommitmessage_Method' => 'ConduitAPIMethod',
'ConduitAPI_differential_setdiffproperty_Method' => 'ConduitAPIMethod',
'ConduitAPI_differential_updaterevision_Method' => 'ConduitAPIMethod',
'ConduitAPI_differential_updatetaskrevisionassoc_Method' => 'ConduitAPIMethod',
'ConduitAPI_differential_updateunitresults_Method' => 'ConduitAPIMethod',
'ConduitAPI_diffusion_getcommits_Method' => 'ConduitAPIMethod',
'ConduitAPI_diffusion_getrecentcommitsbypath_Method' => 'ConduitAPIMethod',
'ConduitAPI_file_download_Method' => 'ConduitAPIMethod',
'ConduitAPI_file_upload_Method' => 'ConduitAPIMethod',
'ConduitAPI_maniphest_info_Method' => 'ConduitAPIMethod',
'ConduitAPI_paste_info_Method' => 'ConduitAPIMethod',
'ConduitAPI_path_getowners_Method' => 'ConduitAPIMethod',
'ConduitAPI_user_find_Method' => 'ConduitAPIMethod',
'ConduitAPI_user_whoami_Method' => 'ConduitAPIMethod',
'DarkConsoleConfigPlugin' => 'DarkConsolePlugin',
'DarkConsoleController' => 'PhabricatorController',
'DarkConsoleErrorLogPlugin' => 'DarkConsolePlugin',
'DarkConsoleRequestPlugin' => 'DarkConsolePlugin',
'DarkConsoleServicesPlugin' => 'DarkConsolePlugin',
'DarkConsoleXHProfPlugin' => 'DarkConsolePlugin',
'DifferentialAddCommentView' => 'AphrontView',
'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',
'DifferentialExceptionMail' => 'DifferentialMail',
'DifferentialHunk' => 'DifferentialDAO',
'DifferentialInlineComment' => 'DifferentialDAO',
'DifferentialInlineCommentEditController' => 'DifferentialController',
'DifferentialInlineCommentPreviewController' => 'DifferentialController',
'DifferentialInlineCommentView' => 'AphrontView',
'DifferentialNewDiffMail' => 'DifferentialReviewRequestMail',
'DifferentialPrimaryPaneView' => 'AphrontView',
'DifferentialReplyHandler' => 'PhabricatorMailReplyHandler',
'DifferentialReviewRequestMail' => 'DifferentialMail',
'DifferentialRevision' => 'DifferentialDAO',
'DifferentialRevisionCommentListView' => 'AphrontView',
'DifferentialRevisionCommentView' => 'AphrontView',
'DifferentialRevisionDetailView' => 'AphrontView',
'DifferentialRevisionEditController' => 'DifferentialController',
'DifferentialRevisionListController' => 'DifferentialController',
'DifferentialRevisionUpdateHistoryView' => 'AphrontView',
'DifferentialRevisionViewController' => 'DifferentialController',
'DifferentialSubscribeController' => 'DifferentialController',
'DifferentialViewTime' => 'DifferentialDAO',
'DiffusionBranchTableView' => 'DiffusionView',
'DiffusionBrowseController' => 'DiffusionController',
'DiffusionBrowseFileController' => 'DiffusionController',
'DiffusionBrowseTableView' => 'DiffusionView',
'DiffusionChangeController' => 'DiffusionController',
'DiffusionCommitChangeTableView' => 'DiffusionView',
'DiffusionCommitController' => 'DiffusionController',
'DiffusionController' => 'PhabricatorController',
'DiffusionDiffController' => 'DiffusionController',
'DiffusionGitBranchQuery' => 'DiffusionBranchQuery',
'DiffusionGitBrowseQuery' => 'DiffusionBrowseQuery',
'DiffusionGitDiffQuery' => 'DiffusionDiffQuery',
'DiffusionGitFileContentQuery' => 'DiffusionFileContentQuery',
'DiffusionGitHistoryQuery' => 'DiffusionHistoryQuery',
'DiffusionGitLastModifiedQuery' => 'DiffusionLastModifiedQuery',
'DiffusionGitRequest' => 'DiffusionRequest',
'DiffusionHistoryController' => 'DiffusionController',
'DiffusionHistoryTableView' => 'DiffusionView',
'DiffusionHomeController' => 'DiffusionController',
'DiffusionLastModifiedController' => 'DiffusionController',
'DiffusionPathCompleteController' => 'DiffusionController',
'DiffusionPathValidateController' => 'DiffusionController',
'DiffusionRepositoryController' => 'DiffusionController',
'DiffusionSvnBrowseQuery' => 'DiffusionBrowseQuery',
'DiffusionSvnDiffQuery' => 'DiffusionDiffQuery',
'DiffusionSvnFileContentQuery' => 'DiffusionFileContentQuery',
'DiffusionSvnHistoryQuery' => 'DiffusionHistoryQuery',
'DiffusionSvnLastModifiedQuery' => 'DiffusionLastModifiedQuery',
'DiffusionSvnRequest' => 'DiffusionRequest',
'DiffusionView' => 'AphrontView',
'HeraldAction' => 'HeraldDAO',
'HeraldApplyTranscript' => 'HeraldDAO',
'HeraldCommitAdapter' => 'HeraldObjectAdapter',
'HeraldCondition' => 'HeraldDAO',
'HeraldController' => 'PhabricatorController',
'HeraldDAO' => 'PhabricatorLiskDAO',
'HeraldDeleteController' => 'HeraldController',
'HeraldDifferentialRevisionAdapter' => 'HeraldObjectAdapter',
'HeraldDryRunAdapter' => 'HeraldObjectAdapter',
'HeraldHomeController' => 'HeraldController',
'HeraldNewController' => 'HeraldController',
'HeraldRule' => 'HeraldDAO',
'HeraldRuleController' => 'HeraldController',
'HeraldTestConsoleController' => 'HeraldController',
'HeraldTranscript' => 'HeraldDAO',
'HeraldTranscriptController' => 'HeraldController',
'HeraldTranscriptListController' => 'HeraldController',
'LiskIsolationTestCase' => 'PhabricatorTestCase',
'LiskIsolationTestDAO' => 'LiskDAO',
'ManiphestController' => 'PhabricatorController',
'ManiphestDAO' => 'PhabricatorLiskDAO',
'ManiphestReplyHandler' => 'PhabricatorMailReplyHandler',
'ManiphestTask' => 'ManiphestDAO',
'ManiphestTaskDescriptionChangeController' => 'ManiphestController',
'ManiphestTaskDetailController' => 'ManiphestController',
'ManiphestTaskEditController' => 'ManiphestController',
'ManiphestTaskListController' => 'ManiphestController',
'ManiphestTaskListView' => 'AphrontView',
'ManiphestTaskSummaryView' => 'AphrontView',
'ManiphestTransaction' => 'ManiphestDAO',
'ManiphestTransactionDetailView' => 'AphrontView',
'ManiphestTransactionListView' => 'AphrontView',
'ManiphestTransactionPreviewController' => 'ManiphestController',
'ManiphestTransactionSaveController' => 'ManiphestController',
'Phabricator404Controller' => 'PhabricatorController',
'PhabricatorAuthController' => 'PhabricatorController',
'PhabricatorConduitAPIController' => 'PhabricatorConduitController',
'PhabricatorConduitCertificateToken' => 'PhabricatorConduitDAO',
'PhabricatorConduitConnectionLog' => 'PhabricatorConduitDAO',
'PhabricatorConduitConsoleController' => 'PhabricatorConduitController',
'PhabricatorConduitController' => 'PhabricatorController',
'PhabricatorConduitDAO' => 'PhabricatorLiskDAO',
'PhabricatorConduitLogController' => 'PhabricatorConduitController',
'PhabricatorConduitMethodCallLog' => 'PhabricatorConduitDAO',
'PhabricatorConduitTokenController' => 'PhabricatorConduitController',
'PhabricatorController' => 'AphrontController',
'PhabricatorCountdownController' => 'PhabricatorController',
'PhabricatorCountdownDAO' => 'PhabricatorLiskDAO',
'PhabricatorCountdownDeleteController' => 'PhabricatorCountdownController',
'PhabricatorCountdownEditController' => 'PhabricatorCountdownController',
'PhabricatorCountdownListController' => 'PhabricatorCountdownController',
'PhabricatorCountdownViewController' => 'PhabricatorCountdownController',
'PhabricatorDaemon' => 'PhutilDaemon',
'PhabricatorDaemonCombinedLogController' => 'PhabricatorDaemonController',
'PhabricatorDaemonConsoleController' => 'PhabricatorDaemonController',
'PhabricatorDaemonController' => 'PhabricatorController',
'PhabricatorDaemonDAO' => 'PhabricatorLiskDAO',
'PhabricatorDaemonLog' => 'PhabricatorDaemonDAO',
'PhabricatorDaemonLogEvent' => 'PhabricatorDaemonDAO',
'PhabricatorDaemonLogEventsView' => 'AphrontView',
'PhabricatorDaemonLogListController' => 'PhabricatorDaemonController',
'PhabricatorDaemonLogListView' => 'AphrontView',
'PhabricatorDaemonLogViewController' => 'PhabricatorDaemonController',
'PhabricatorDaemonTimelineConsoleController' => 'PhabricatorDaemonController',
'PhabricatorDaemonTimelineEventController' => 'PhabricatorDaemonController',
'PhabricatorDirectoryCategory' => 'PhabricatorDirectoryDAO',
'PhabricatorDirectoryCategoryDeleteController' => 'PhabricatorDirectoryController',
'PhabricatorDirectoryCategoryEditController' => 'PhabricatorDirectoryController',
'PhabricatorDirectoryCategoryListController' => 'PhabricatorDirectoryController',
'PhabricatorDirectoryController' => 'PhabricatorController',
'PhabricatorDirectoryDAO' => 'PhabricatorLiskDAO',
'PhabricatorDirectoryItem' => 'PhabricatorDirectoryDAO',
'PhabricatorDirectoryItemDeleteController' => 'PhabricatorDirectoryController',
'PhabricatorDirectoryItemEditController' => 'PhabricatorDirectoryController',
'PhabricatorDirectoryItemListController' => 'PhabricatorDirectoryController',
'PhabricatorDirectoryMainController' => 'PhabricatorDirectoryController',
'PhabricatorDisabledUserController' => 'PhabricatorAuthController',
'PhabricatorDraft' => 'PhabricatorDraftDAO',
'PhabricatorDraftDAO' => 'PhabricatorLiskDAO',
'PhabricatorEditPreferencesController' => 'PhabricatorPreferencesController',
'PhabricatorEmailLoginController' => 'PhabricatorAuthController',
'PhabricatorEmailTokenController' => 'PhabricatorAuthController',
'PhabricatorFile' => 'PhabricatorFileDAO',
'PhabricatorFileController' => 'PhabricatorController',
'PhabricatorFileDAO' => 'PhabricatorLiskDAO',
'PhabricatorFileDropUploadController' => 'PhabricatorFileController',
'PhabricatorFileImageMacro' => 'PhabricatorFileDAO',
'PhabricatorFileListController' => 'PhabricatorFileController',
'PhabricatorFileMacroDeleteController' => 'PhabricatorFileController',
'PhabricatorFileMacroEditController' => 'PhabricatorFileController',
'PhabricatorFileMacroListController' => 'PhabricatorFileController',
'PhabricatorFileProxyController' => 'PhabricatorFileController',
'PhabricatorFileProxyImage' => 'PhabricatorFileDAO',
'PhabricatorFileStorageBlob' => 'PhabricatorFileDAO',
'PhabricatorFileTransformController' => 'PhabricatorFileController',
'PhabricatorFileUploadController' => 'PhabricatorFileController',
'PhabricatorFileViewController' => 'PhabricatorFileController',
'PhabricatorGoodForNothingWorker' => 'PhabricatorWorker',
'PhabricatorHelpController' => 'PhabricatorController',
'PhabricatorHelpKeyboardShortcutController' => 'PhabricatorHelpController',
'PhabricatorIRCBot' => 'PhabricatorDaemon',
'PhabricatorIRCObjectNameHandler' => 'PhabricatorIRCHandler',
'PhabricatorIRCProtocolHandler' => 'PhabricatorIRCHandler',
'PhabricatorJavelinLinter' => 'ArcanistLinter',
'PhabricatorLintEngine' => 'PhutilLintEngine',
'PhabricatorLiskDAO' => 'LiskDAO',
'PhabricatorLoginController' => 'PhabricatorAuthController',
'PhabricatorLogoutController' => 'PhabricatorAuthController',
'PhabricatorMailImplementationAmazonSESAdapter' => 'PhabricatorMailImplementationPHPMailerLiteAdapter',
'PhabricatorMailImplementationPHPMailerLiteAdapter' => 'PhabricatorMailImplementationAdapter',
'PhabricatorMailImplementationSendGridAdapter' => 'PhabricatorMailImplementationAdapter',
'PhabricatorMailImplementationTestAdapter' => 'PhabricatorMailImplementationAdapter',
'PhabricatorMetaMTAController' => 'PhabricatorController',
'PhabricatorMetaMTADAO' => 'PhabricatorLiskDAO',
'PhabricatorMetaMTADaemon' => 'PhabricatorDaemon',
'PhabricatorMetaMTAEmailBodyParserTestCase' => 'PhabricatorTestCase',
'PhabricatorMetaMTAListController' => 'PhabricatorMetaMTAController',
'PhabricatorMetaMTAMail' => 'PhabricatorMetaMTADAO',
'PhabricatorMetaMTAMailTestCase' => 'PhabricatorTestCase',
'PhabricatorMetaMTAMailingList' => 'PhabricatorMetaMTADAO',
'PhabricatorMetaMTAMailingListEditController' => 'PhabricatorMetaMTAController',
'PhabricatorMetaMTAMailingListsController' => 'PhabricatorMetaMTAController',
'PhabricatorMetaMTAReceiveController' => 'PhabricatorMetaMTAController',
'PhabricatorMetaMTAReceivedListController' => 'PhabricatorMetaMTAController',
'PhabricatorMetaMTAReceivedMail' => 'PhabricatorMetaMTADAO',
'PhabricatorMetaMTASendController' => 'PhabricatorMetaMTAController',
'PhabricatorMetaMTASendGridReceiveController' => 'PhabricatorMetaMTAController',
'PhabricatorMetaMTAViewController' => 'PhabricatorMetaMTAController',
'PhabricatorOAuthDefaultRegistrationController' => 'PhabricatorOAuthRegistrationController',
'PhabricatorOAuthDiagnosticsController' => 'PhabricatorAuthController',
'PhabricatorOAuthFailureView' => 'AphrontView',
'PhabricatorOAuthLoginController' => 'PhabricatorAuthController',
'PhabricatorOAuthProviderFacebook' => 'PhabricatorOAuthProvider',
'PhabricatorOAuthProviderGithub' => 'PhabricatorOAuthProvider',
'PhabricatorOAuthRegistrationController' => 'PhabricatorAuthController',
'PhabricatorOAuthUnlinkController' => 'PhabricatorAuthController',
'PhabricatorOwnersController' => 'PhabricatorController',
'PhabricatorOwnersDAO' => 'PhabricatorLiskDAO',
'PhabricatorOwnersDeleteController' => 'PhabricatorOwnersController',
'PhabricatorOwnersDetailController' => 'PhabricatorOwnersController',
'PhabricatorOwnersEditController' => 'PhabricatorOwnersController',
'PhabricatorOwnersListController' => 'PhabricatorOwnersController',
'PhabricatorOwnersOwner' => 'PhabricatorOwnersDAO',
'PhabricatorOwnersPackage' => 'PhabricatorOwnersDAO',
'PhabricatorOwnersPath' => 'PhabricatorOwnersDAO',
'PhabricatorPHID' => 'PhabricatorPHIDDAO',
'PhabricatorPHIDAllocateController' => 'PhabricatorPHIDController',
'PhabricatorPHIDController' => 'PhabricatorController',
'PhabricatorPHIDDAO' => 'PhabricatorLiskDAO',
'PhabricatorPHIDListController' => 'PhabricatorPHIDController',
'PhabricatorPHIDLookupController' => 'PhabricatorPHIDController',
'PhabricatorPaste' => 'PhabricatorPasteDAO',
'PhabricatorPasteController' => 'PhabricatorController',
'PhabricatorPasteCreateController' => 'PhabricatorPasteController',
'PhabricatorPasteDAO' => 'PhabricatorLiskDAO',
'PhabricatorPasteListController' => 'PhabricatorPasteController',
'PhabricatorPasteViewController' => 'PhabricatorPasteController',
'PhabricatorPeopleController' => 'PhabricatorController',
'PhabricatorPeopleEditController' => 'PhabricatorPeopleController',
'PhabricatorPeopleListController' => 'PhabricatorPeopleController',
'PhabricatorPeopleLogsController' => 'PhabricatorPeopleController',
'PhabricatorPeopleProfileController' => 'PhabricatorPeopleController',
'PhabricatorPeopleProfileEditController' => 'PhabricatorPeopleController',
'PhabricatorPreferencesController' => 'PhabricatorController',
'PhabricatorProfileView' => 'AphrontView',
'PhabricatorProject' => 'PhabricatorProjectDAO',
'PhabricatorProjectAffiliation' => 'PhabricatorProjectDAO',
'PhabricatorProjectAffiliationEditController' => 'PhabricatorProjectController',
'PhabricatorProjectController' => 'PhabricatorController',
+ 'PhabricatorProjectCreateController' => 'PhabricatorProjectController',
'PhabricatorProjectDAO' => 'PhabricatorLiskDAO',
'PhabricatorProjectListController' => 'PhabricatorProjectController',
'PhabricatorProjectProfile' => 'PhabricatorProjectDAO',
'PhabricatorProjectProfileController' => 'PhabricatorProjectController',
'PhabricatorProjectProfileEditController' => 'PhabricatorProjectController',
- 'PhabricatorProjectQuickCreateController' => 'PhabricatorProjectController',
'PhabricatorRedirectController' => 'PhabricatorController',
'PhabricatorRemarkupRuleDifferential' => 'PhabricatorRemarkupRuleObjectName',
'PhabricatorRemarkupRuleDiffusion' => 'PhutilRemarkupRule',
'PhabricatorRemarkupRuleImageMacro' => 'PhutilRemarkupRule',
'PhabricatorRemarkupRuleManiphest' => 'PhabricatorRemarkupRuleObjectName',
'PhabricatorRemarkupRuleMention' => 'PhutilRemarkupRule',
'PhabricatorRemarkupRuleObjectName' => 'PhutilRemarkupRule',
'PhabricatorRemarkupRuleProxyImage' => 'PhutilRemarkupRule',
'PhabricatorRemarkupRuleYoutube' => 'PhutilRemarkupRule',
'PhabricatorRepository' => 'PhabricatorRepositoryDAO',
'PhabricatorRepositoryArcanistProject' => 'PhabricatorRepositoryDAO',
'PhabricatorRepositoryArcanistProjectEditController' => 'PhabricatorRepositoryController',
'PhabricatorRepositoryCommit' => 'PhabricatorRepositoryDAO',
'PhabricatorRepositoryCommitChangeParserWorker' => 'PhabricatorRepositoryCommitParserWorker',
'PhabricatorRepositoryCommitData' => 'PhabricatorRepositoryDAO',
'PhabricatorRepositoryCommitDiscoveryDaemon' => 'PhabricatorRepositoryDaemon',
'PhabricatorRepositoryCommitHeraldWorker' => 'PhabricatorRepositoryCommitParserWorker',
'PhabricatorRepositoryCommitMessageParserWorker' => 'PhabricatorRepositoryCommitParserWorker',
'PhabricatorRepositoryCommitParserWorker' => 'PhabricatorWorker',
'PhabricatorRepositoryCommitTaskDaemon' => 'PhabricatorRepositoryDaemon',
'PhabricatorRepositoryController' => 'PhabricatorController',
'PhabricatorRepositoryCreateController' => 'PhabricatorRepositoryController',
'PhabricatorRepositoryDAO' => 'PhabricatorLiskDAO',
'PhabricatorRepositoryDaemon' => 'PhabricatorDaemon',
'PhabricatorRepositoryDefaultCommitMessageDetailParser' => 'PhabricatorRepositoryCommitMessageDetailParser',
'PhabricatorRepositoryDeleteController' => 'PhabricatorRepositoryController',
'PhabricatorRepositoryEditController' => 'PhabricatorRepositoryController',
'PhabricatorRepositoryGitCommitChangeParserWorker' => 'PhabricatorRepositoryCommitChangeParserWorker',
'PhabricatorRepositoryGitCommitDiscoveryDaemon' => 'PhabricatorRepositoryCommitDiscoveryDaemon',
'PhabricatorRepositoryGitCommitMessageParserWorker' => 'PhabricatorRepositoryCommitMessageParserWorker',
'PhabricatorRepositoryGitFetchDaemon' => 'PhabricatorRepositoryDaemon',
'PhabricatorRepositoryGitHubNotification' => 'PhabricatorRepositoryDAO',
'PhabricatorRepositoryGitHubPostReceiveController' => 'PhabricatorRepositoryController',
'PhabricatorRepositoryListController' => 'PhabricatorRepositoryController',
'PhabricatorRepositoryShortcut' => 'PhabricatorRepositoryDAO',
'PhabricatorRepositorySvnCommitChangeParserWorker' => 'PhabricatorRepositoryCommitChangeParserWorker',
'PhabricatorRepositorySvnCommitDiscoveryDaemon' => 'PhabricatorRepositoryCommitDiscoveryDaemon',
'PhabricatorRepositorySvnCommitMessageParserWorker' => 'PhabricatorRepositoryCommitMessageParserWorker',
'PhabricatorSearchAttachController' => 'PhabricatorSearchController',
'PhabricatorSearchBaseController' => 'PhabricatorController',
'PhabricatorSearchCommitIndexer' => 'PhabricatorSearchDocumentIndexer',
'PhabricatorSearchController' => 'PhabricatorSearchBaseController',
'PhabricatorSearchDAO' => 'PhabricatorLiskDAO',
'PhabricatorSearchDifferentialIndexer' => 'PhabricatorSearchDocumentIndexer',
'PhabricatorSearchDocument' => 'PhabricatorSearchDAO',
'PhabricatorSearchDocumentField' => 'PhabricatorSearchDAO',
'PhabricatorSearchDocumentRelationship' => 'PhabricatorSearchDAO',
'PhabricatorSearchIndexController' => 'PhabricatorSearchBaseController',
'PhabricatorSearchManiphestIndexer' => 'PhabricatorSearchDocumentIndexer',
'PhabricatorSearchMySQLExecutor' => 'PhabricatorSearchExecutor',
'PhabricatorSearchQuery' => 'PhabricatorSearchDAO',
'PhabricatorSearchSelectController' => 'PhabricatorSearchController',
'PhabricatorSearchUserIndexer' => 'PhabricatorSearchDocumentIndexer',
'PhabricatorStandardPageView' => 'AphrontPageView',
'PhabricatorStatusController' => 'PhabricatorController',
'PhabricatorTaskmasterDaemon' => 'PhabricatorDaemon',
'PhabricatorTestCase' => 'ArcanistPhutilTestCase',
'PhabricatorTimelineCursor' => 'PhabricatorTimelineDAO',
'PhabricatorTimelineDAO' => 'PhabricatorLiskDAO',
'PhabricatorTimelineEvent' => 'PhabricatorTimelineDAO',
'PhabricatorTimelineEventData' => 'PhabricatorTimelineDAO',
'PhabricatorTimer' => 'PhabricatorCountdownDAO',
'PhabricatorTransformedFile' => 'PhabricatorFileDAO',
'PhabricatorTypeaheadCommonDatasourceController' => 'PhabricatorTypeaheadDatasourceController',
'PhabricatorTypeaheadDatasourceController' => 'PhabricatorController',
'PhabricatorUIExampleController' => 'PhabricatorController',
'PhabricatorUIExampleRenderController' => 'PhabricatorUIExampleController',
'PhabricatorUIListFilterExample' => 'PhabricatorUIExample',
'PhabricatorUIPagerExample' => 'PhabricatorUIExample',
'PhabricatorUser' => 'PhabricatorUserDAO',
'PhabricatorUserDAO' => 'PhabricatorLiskDAO',
'PhabricatorUserLog' => 'PhabricatorUserDAO',
'PhabricatorUserOAuthInfo' => 'PhabricatorUserDAO',
'PhabricatorUserPreferences' => 'PhabricatorUserDAO',
'PhabricatorUserProfile' => 'PhabricatorUserDAO',
'PhabricatorUserSettingsController' => 'PhabricatorPeopleController',
'PhabricatorWorkerDAO' => 'PhabricatorLiskDAO',
'PhabricatorWorkerTask' => 'PhabricatorWorkerDAO',
'PhabricatorWorkerTaskData' => 'PhabricatorWorkerDAO',
'PhabricatorWorkerTaskDetailController' => 'PhabricatorDaemonController',
'PhabricatorXHPASTViewController' => 'PhabricatorController',
'PhabricatorXHPASTViewDAO' => 'PhabricatorLiskDAO',
'PhabricatorXHPASTViewFrameController' => 'PhabricatorXHPASTViewController',
'PhabricatorXHPASTViewFramesetController' => 'PhabricatorXHPASTViewController',
'PhabricatorXHPASTViewInputController' => 'PhabricatorXHPASTViewPanelController',
'PhabricatorXHPASTViewPanelController' => 'PhabricatorXHPASTViewController',
'PhabricatorXHPASTViewParseTree' => 'PhabricatorXHPASTViewDAO',
'PhabricatorXHPASTViewRunController' => 'PhabricatorXHPASTViewController',
'PhabricatorXHPASTViewStreamController' => 'PhabricatorXHPASTViewPanelController',
'PhabricatorXHPASTViewTreeController' => 'PhabricatorXHPASTViewPanelController',
'PhabricatorXHProfController' => 'PhabricatorController',
'PhabricatorXHProfProfileController' => 'PhabricatorXHProfController',
'PhabricatorXHProfProfileSymbolView' => 'AphrontView',
'PhabricatorXHProfProfileTopLevelView' => 'AphrontView',
),
'requires_interface' =>
array(
),
));
diff --git a/src/aphront/default/configuration/AphrontDefaultApplicationConfiguration.php b/src/aphront/default/configuration/AphrontDefaultApplicationConfiguration.php
index 42ff0a847c..a76b31a783 100644
--- a/src/aphront/default/configuration/AphrontDefaultApplicationConfiguration.php
+++ b/src/aphront/default/configuration/AphrontDefaultApplicationConfiguration.php
@@ -1,447 +1,447 @@
<?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 aphront
*/
class AphrontDefaultApplicationConfiguration
extends AphrontApplicationConfiguration {
public function __construct() {
}
public function getApplicationName() {
return 'aphront-default';
}
public function getURIMap() {
return $this->getResourceURIMapRules() + array(
'/' => array(
'$' => 'PhabricatorDirectoryMainController',
),
'/directory/' => array(
'item/$'
=> 'PhabricatorDirectoryItemListController',
'item/edit/(?:(?P<id>\d+)/)?$'
=> 'PhabricatorDirectoryItemEditController',
'item/delete/(?P<id>\d+)/'
=> 'PhabricatorDirectoryItemDeleteController',
'category/$'
=> 'PhabricatorDirectoryCategoryListController',
'category/edit/(?:(?P<id>\d+)/)?$'
=> 'PhabricatorDirectoryCategoryEditController',
'category/delete/(?P<id>\d+)/'
=> 'PhabricatorDirectoryCategoryDeleteController',
),
'/file/' => array(
'$' => 'PhabricatorFileListController',
'upload/$' => 'PhabricatorFileUploadController',
'dropupload/$' => 'PhabricatorFileDropUploadController',
'(?P<view>info)/(?P<phid>[^/]+)/' => 'PhabricatorFileViewController',
'(?P<view>view)/(?P<phid>[^/]+)/' => 'PhabricatorFileViewController',
'(?P<view>download)/(?P<phid>[^/]+)/' => 'PhabricatorFileViewController',
'macro/' => array(
'$' => 'PhabricatorFileMacroListController',
'edit/(?:(?P<id>\d+)/)?$' => 'PhabricatorFileMacroEditController',
'delete/(?P<id>\d+)/$' => 'PhabricatorFileMacroDeleteController',
),
'proxy/$' => 'PhabricatorFileProxyController',
'xform/(?P<transform>[^/]+)/(?P<phid>[^/]+)/'
=> 'PhabricatorFileTransformController',
),
'/phid/' => array(
'$' => 'PhabricatorPHIDLookupController',
'list/$' => 'PhabricatorPHIDListController',
'new/$' => 'PhabricatorPHIDAllocateController',
),
'/people/' => array(
'$' => 'PhabricatorPeopleListController',
'logs/$' => 'PhabricatorPeopleLogsController',
'edit/(?:(?P<id>\d+)/(?:(?P<view>\w+)/)?)?$'
=> 'PhabricatorPeopleEditController',
),
'/p/(?P<username>\w+)/(?:(?P<page>\w+)/)?$'
=> 'PhabricatorPeopleProfileController',
'/profile/' => array(
'edit/$' => 'PhabricatorPeopleProfileEditController',
),
'/conduit/' => array(
'$' => 'PhabricatorConduitConsoleController',
'method/(?P<method>[^/]+)$' => 'PhabricatorConduitConsoleController',
'log/$' => 'PhabricatorConduitLogController',
'token/$' => 'PhabricatorConduitTokenController',
),
'/api/(?P<method>[^/]+)$' => 'PhabricatorConduitAPIController',
'/D(?P<id>\d+)' => 'DifferentialRevisionViewController',
'/differential/' => array(
'$' => 'DifferentialRevisionListController',
'filter/(?P<filter>\w+)/$' => 'DifferentialRevisionListController',
'diff/' => array(
'(?P<id>\d+)/$' => 'DifferentialDiffViewController',
'create/$' => 'DifferentialDiffCreateController',
),
'changeset/$' => 'DifferentialChangesetViewController',
'revision/edit/(?:(?P<id>\d+)/)?$'
=> 'DifferentialRevisionEditController',
'comment/' => array(
'preview/(?P<id>\d+)/$' => 'DifferentialCommentPreviewController',
'save/$' => 'DifferentialCommentSaveController',
'inline/' => array(
'preview/(?P<id>\d+)/$' =>
'DifferentialInlineCommentPreviewController',
'edit/(?P<id>\d+)/$' => 'DifferentialInlineCommentEditController',
),
),
'subscribe/(?P<action>add|rem)/(?P<id>\d+)/$'
=> 'DifferentialSubscribeController',
),
'/typeahead/' => array(
'common/(?P<type>\w+)/$'
=> 'PhabricatorTypeaheadCommonDatasourceController',
),
'/mail/' => array(
'$' => 'PhabricatorMetaMTAListController',
'send/$' => 'PhabricatorMetaMTASendController',
'view/(?P<id>\d+)/$' => 'PhabricatorMetaMTAViewController',
'lists/$' => 'PhabricatorMetaMTAMailingListsController',
'lists/edit/(?:(?P<id>\d+)/)?$'
=> 'PhabricatorMetaMTAMailingListEditController',
'receive/$' => 'PhabricatorMetaMTAReceiveController',
'received/$' => 'PhabricatorMetaMTAReceivedListController',
'sendgrid/$' => 'PhabricatorMetaMTASendGridReceiveController',
),
'/login/' => array(
'$' => 'PhabricatorLoginController',
'email/$' => 'PhabricatorEmailLoginController',
'etoken/(?P<token>\w+)/$' => 'PhabricatorEmailTokenController',
),
'/logout/$' => 'PhabricatorLogoutController',
'/oauth/' => array(
'(?P<provider>github|facebook)/' => array(
'login/$' => 'PhabricatorOAuthLoginController',
'diagnose/$' => 'PhabricatorOAuthDiagnosticsController',
'unlink/$' => 'PhabricatorOAuthUnlinkController',
),
),
'/xhprof/' => array(
'profile/(?P<phid>[^/]+)/$' => 'PhabricatorXHProfProfileController',
),
'/~/' => 'DarkConsoleController',
'/settings/' => array(
'(?:page/(?P<page>[^/]+)/)?$' => 'PhabricatorUserSettingsController',
),
'/maniphest/' => array(
'$' => 'ManiphestTaskListController',
'view/(?P<view>\w+)/$' => 'ManiphestTaskListController',
'task/' => array(
'create/$' => 'ManiphestTaskEditController',
'edit/(?P<id>\d+)/$' => 'ManiphestTaskEditController',
'descriptionchange/(?P<id>\d+)/$' =>
'ManiphestTaskDescriptionChangeController',
),
'transaction/' => array(
'save/' => 'ManiphestTransactionSaveController',
'preview/(?P<id>\d+)/$' => 'ManiphestTransactionPreviewController',
),
),
'/T(?P<id>\d+)$' => 'ManiphestTaskDetailController',
'/github-post-receive/(?P<id>\d+)/(?P<token>[^/]+)/$'
=> 'PhabricatorRepositoryGitHubPostReceiveController',
'/repository/' => array(
'$' => 'PhabricatorRepositoryListController',
'create/$' => 'PhabricatorRepositoryCreateController',
'edit/(?P<id>\d+)/(?:(?P<view>\w+)?/)?$' =>
'PhabricatorRepositoryEditController',
'delete/(?P<id>\d+)/$' => 'PhabricatorRepositoryDeleteController',
'project/(?P<id>\d+)/' =>
'PhabricatorRepositoryArcanistProjectEditController',
),
'/search/' => array(
'$' => 'PhabricatorSearchController',
'(?P<id>\d+)/$' => 'PhabricatorSearchController',
'attach/(?P<phid>[^/]+)/(?P<type>\w+)/(?:(?P<action>\w+)/)?$'
=> 'PhabricatorSearchAttachController',
'select/(?P<type>\w+)/$'
=> 'PhabricatorSearchSelectController',
'index/(?P<phid>[^/]+)/$' => 'PhabricatorSearchIndexController',
),
'/project/' => array(
'$' => 'PhabricatorProjectListController',
- 'edit/(?:(?P<id>\d+)/)?$' => 'PhabricatorProjectProfileEditController',
+ 'edit/(?P<id>\d+)/$' => 'PhabricatorProjectProfileEditController',
'view/(?P<id>\d+)/(?:(?P<page>\w+)/)?$'
=> 'PhabricatorProjectProfileController',
'affiliation/(?P<id>\d+)/$'
=> 'PhabricatorProjectAffiliationEditController',
- 'quickcreate/$' => 'PhabricatorProjectQuickCreateController',
+ 'create/$' => 'PhabricatorProjectCreateController',
),
'/r(?P<callsign>[A-Z]+)(?P<commit>[a-z0-9]+)$'
=> 'DiffusionCommitController',
'/diffusion/' => array(
'$' => 'DiffusionHomeController',
'(?P<callsign>[A-Z]+)/' => array(
'$' => 'DiffusionRepositoryController',
'repository/'.
'(?P<path>[^/]+)/'.
'$'
=> 'DiffusionRepositoryController',
'change/'.
'(?P<path>.*?)'.
'(?:[;](?P<commit>[a-z0-9]+))?'.
'$'
=> 'DiffusionChangeController',
'history/'.
'(?P<path>.*?)'.
'(?:[;](?P<commit>[a-z0-9]+))?'.
'$'
=> 'DiffusionHistoryController',
'browse/'.
'(?P<path>.*?)'.
'(?:[;](?P<commit>[a-z0-9]+))?'.
'(?:[$](?P<line>\d+))?'.
'$'
=> 'DiffusionBrowseController',
'diff/'.
'(?P<path>.*?)'.
'(?:[;](?P<commit>[a-z0-9]+))?'.
'$'
=> 'DiffusionDiffController',
'lastmodified/'.
'(?P<path>.*?)'.
'(?:[;](?P<commit>[a-z0-9]+))?'.
'$'
=> 'DiffusionLastModifiedController',
),
'services/' => array(
'path/' => array(
'complete/$' => 'DiffusionPathCompleteController',
'validate/$' => 'DiffusionPathValidateController',
),
),
),
'/daemon/' => array(
'task/(?P<id>\d+)/$' => 'PhabricatorWorkerTaskDetailController',
'log/' => array(
'$' => 'PhabricatorDaemonLogListController',
'combined/$' => 'PhabricatorDaemonCombinedLogController',
'(?P<id>\d+)/$' => 'PhabricatorDaemonLogViewController',
),
'timeline/$' => 'PhabricatorDaemonTimelineConsoleController',
'timeline/(?P<id>\d+)/$' => 'PhabricatorDaemonTimelineEventController',
'$' => 'PhabricatorDaemonConsoleController',
),
'/herald/' => array(
'$' => 'HeraldHomeController',
'view/(?P<view>[^/]+)/$' => 'HeraldHomeController',
'new/(?:(?P<type>[^/]+)/)?$' => 'HeraldNewController',
'rule/(?:(?P<id>\d+)/)?$' => 'HeraldRuleController',
'delete/(?P<id>\d+)/$' => 'HeraldDeleteController',
'test/$' => 'HeraldTestConsoleController',
'transcript/$' => 'HeraldTranscriptListController',
'transcript/(?P<id>\d+)/(?:(?P<filter>\w+)/)?$'
=> 'HeraldTranscriptController',
),
'/preferences/' => array(
'$' => 'PhabricatorEditPreferencesController'
),
'/uiexample/' => array(
'$' => 'PhabricatorUIExampleRenderController',
'view/(?P<class>[^/]+)/$' => 'PhabricatorUIExampleRenderController',
),
'/owners/' => array(
'$' => 'PhabricatorOwnersListController',
'view/(?P<view>[^/]+)/$' => 'PhabricatorOwnersListController',
'edit/(?P<id>\d+)/$' => 'PhabricatorOwnersEditController',
'new/$' => 'PhabricatorOwnersEditController',
'package/(?P<id>\d+)/$' => 'PhabricatorOwnersDetailController',
'delete/(?P<id>\d+)/$' => 'PhabricatorOwnersDeleteController',
),
'/xhpast/' => array(
'$' => 'PhabricatorXHPASTViewRunController',
'view/(?P<id>\d+)/$'
=> 'PhabricatorXHPASTViewFrameController',
'frameset/(?P<id>\d+)/$'
=> 'PhabricatorXHPASTViewFramesetController',
'input/(?P<id>\d+)/$'
=> 'PhabricatorXHPASTViewInputController',
'tree/(?P<id>\d+)/$'
=> 'PhabricatorXHPASTViewTreeController',
'stream/(?P<id>\d+)/$'
=> 'PhabricatorXHPASTViewStreamController',
),
'/status/$' => 'PhabricatorStatusController',
'/paste/' => array(
'$' => 'PhabricatorPasteCreateController',
'list/' => 'PhabricatorPasteListController',
),
'/P(?P<id>\d+)$' => 'PhabricatorPasteViewController',
'/help/' => array(
'keyboardshortcut/$' => 'PhabricatorHelpKeyboardShortcutController',
),
'/countdown/' => array(
'$'
=> 'PhabricatorCountdownListController',
'(?P<id>\d+)/$'
=> 'PhabricatorCountdownViewController',
'edit/(?:(?P<id>\d+)/)?$'
=> 'PhabricatorCountdownEditController',
'delete/(?P<id>\d+)/$'
=> 'PhabricatorCountdownDeleteController'
),
);
}
protected function getResourceURIMapRules() {
return array(
'/res/' => array(
'(?P<package>pkg/)?(?P<hash>[a-f0-9]{8})/(?P<path>.+\.(?:css|js))$'
=> 'CelerityResourceController',
),
);
}
public function buildRequest() {
$request = new AphrontRequest($this->getHost(), $this->getPath());
$request->setRequestData($_GET + $_POST);
$request->setApplicationConfiguration($this);
return $request;
}
public function handleException(Exception $ex) {
// Always log the unhandled exception.
phlog($ex);
$class = phutil_escape_html(get_class($ex));
$message = phutil_escape_html($ex->getMessage());
$content =
'<div class="aphront-unhandled-exception">'.
'<h1>Unhandled Exception "'.$class.'": '.$message.'</h1>'.
'<code>'.phutil_escape_html((string)$ex).'</code>'.
'</div>';
$user = $this->getRequest()->getUser();
if (!$user) {
// If we hit an exception very early, we won't have a user.
$user = new PhabricatorUser();
}
$dialog = new AphrontDialogView();
$dialog
->setTitle('Exception!')
->setClass('aphront-exception-dialog')
->setUser($user)
->appendChild($content)
->addCancelButton('/');
$response = new AphrontDialogResponse();
$response->setDialog($dialog);
return $response;
}
public function willSendResponse(AphrontResponse $response) {
$request = $this->getRequest();
$response->setRequest($request);
if ($response instanceof AphrontDialogResponse) {
if (!$request->isAjax()) {
$view = new PhabricatorStandardPageView();
$view->setRequest($request);
$view->appendChild(
'<div style="padding: 2em 0;">'.
$response->buildResponseString().
'</div>');
$response = new AphrontWebpageResponse();
$response->setContent($view->render());
return $response;
} else {
return id(new AphrontAjaxResponse())
->setContent(array(
'dialog' => $response->buildResponseString(),
));
}
} else if ($response instanceof AphrontRedirectResponse) {
if ($request->isAjax()) {
return id(new AphrontAjaxResponse())
->setContent(
array(
'redirect' => $response->getURI(),
));
}
} else if ($response instanceof Aphront404Response) {
$failure = new AphrontRequestFailureView();
$failure->setHeader('404 Not Found');
$failure->appendChild(
'<p>The page you requested was not found.</p>');
$view = new PhabricatorStandardPageView();
$view->setTitle('404 Not Found');
$view->setRequest($this->getRequest());
$view->appendChild($failure);
$response = new AphrontWebpageResponse();
$response->setContent($view->render());
$response->setHTTPResponseCode(404);
return $response;
}
return $response;
}
public function build404Controller() {
return array(new Phabricator404Controller($this->getRequest()), array());
}
public function buildRedirectController($uri) {
return array(
new PhabricatorRedirectController($this->getRequest()),
array(
'uri' => $uri,
));
}
}
diff --git a/src/applications/files/controller/transform/PhabricatorFileTransformController.php b/src/applications/files/controller/transform/PhabricatorFileTransformController.php
index 7f3a42253d..c2b777233d 100644
--- a/src/applications/files/controller/transform/PhabricatorFileTransformController.php
+++ b/src/applications/files/controller/transform/PhabricatorFileTransformController.php
@@ -1,178 +1,123 @@
<?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 PhabricatorFileTransformController extends PhabricatorFileController {
private $transform;
private $phid;
public function willProcessRequest(array $data) {
$this->transform = $data['transform'];
$this->phid = $data['phid'];
}
public function processRequest() {
$xform = id(new PhabricatorTransformedFile())
->loadOneWhere(
'originalPHID = %s AND transform = %s',
$this->phid,
$this->transform);
if ($xform) {
return $this->buildTransformedFileResponse($xform);
}
$file = id(new PhabricatorFile())->loadOneWhere('phid = %s', $this->phid);
if (!$file) {
return new Aphront404Response();
}
$type = $file->getMimeType();
if (!$file->isViewableInBrowser() || !$file->isTransformableImage()) {
return $this->buildDefaultTransformation($file);
}
switch ($this->transform) {
case 'thumb-160x120':
$xformed_file = $this->executeThumbTransform($file, 160, 120);
break;
case 'thumb-60x45':
$xformed_file = $this->executeThumbTransform($file, 60, 45);
break;
- case 'profile-50x50':
- $xformed_file = $this->executeProfile50x50Transform($file);
- break;
default:
return new Aphront400Response();
}
if (!$xformed_file) {
return new Aphront400Response();
}
$xform = new PhabricatorTransformedFile();
$xform->setOriginalPHID($this->phid);
$xform->setTransform($this->transform);
$xform->setTransformedPHID($xformed_file->getPHID());
$xform->save();
return $this->buildTransformedFileResponse($xform);
}
private function buildDefaultTransformation(PhabricatorFile $file) {
static $regexps = array(
'@application/zip@' => 'zip',
'@image/@' => 'image',
'@application/pdf@' => 'pdf',
'@.*@' => 'default',
);
$type = $file->getMimeType();
$prefix = 'default';
foreach ($regexps as $regexp => $implied_prefix) {
if (preg_match($regexp, $type)) {
$prefix = $implied_prefix;
break;
}
}
switch ($this->transform) {
case 'thumb-160x120':
$suffix = '160x120';
break;
case 'thumb-60x45':
$suffix = '60x45';
break;
default:
throw new Exception("Unsupported transformation type!");
}
$path = "/rsrc/image/icon/fatcow/thumbnails/{$prefix}{$suffix}.png";
return id(new AphrontRedirectResponse())
->setURI($path);
}
private function buildTransformedFileResponse(
PhabricatorTransformedFile $xform) {
// TODO: We could just delegate to the file view controller instead,
// which would save the client a roundtrip, but is slightly more complex.
return id(new AphrontRedirectResponse())->setURI(
PhabricatorFileURI::getViewURIForPHID($xform->getTransformedPHID()));
}
- private function executeProfile50x50Transform(PhabricatorFile $file) {
- $data = $file->loadFileData();
- $jpeg = $this->crudelyScaleTo($data, 50, 50);
-
- return PhabricatorFile::newFromFileData($jpeg, array(
- 'name' => 'profile-'.$file->getName(),
- ));
- }
-
private function executeThumbTransform(PhabricatorFile $file, $x, $y) {
- $data = $file->loadFileData();
- $jpeg = $this->crudelyScaleTo($data, $x, $y);
- return PhabricatorFile::newFromFileData($jpeg, array(
- 'name' => 'thumb-'.$file->getName(),
- ));
- }
-
- /**
- * Very crudely scale an image up or down to an exact size.
- */
- private function crudelyScaleTo($data, $dx, $dy) {
- $src = imagecreatefromstring($data);
- $x = imagesx($src);
- $y = imagesy($src);
-
- $scale = min($x / $dx, $y / $dy);
- $dst = imagecreatetruecolor($dx, $dy);
-
- imagecopyresampled(
- $dst,
- $src,
- 0, 0,
- 0, 0,
- $dx, $dy,
- $scale * $dx, $scale * $dy);
-
- $img = null;
-
- if (function_exists('imagejpeg')) {
- ob_start();
- imagejpeg($dst);
- $img = ob_get_clean();
- } else if (function_exists('imagepng')) {
- ob_start();
- imagepng($dst);
- $img = ob_get_clean();
- } else if (function_exists('imagegif')) {
- ob_start();
- imagegif($dst);
- $img = ob_get_clean();
- } else {
- throw new Exception("No image generation functions exist!");
- }
-
- return $img;
+ $xformer = new PhabricatorImageTransformer();
+ return $xformer->executeThumbTransform($file, $x, $y);
}
}
diff --git a/src/applications/files/controller/transform/__init__.php b/src/applications/files/controller/transform/__init__.php
index ee7607aff0..296cae409a 100644
--- a/src/applications/files/controller/transform/__init__.php
+++ b/src/applications/files/controller/transform/__init__.php
@@ -1,20 +1,21 @@
<?php
/**
* This file is automatically generated. Lint this module to rebuild it.
* @generated
*/
phutil_require_module('phabricator', 'aphront/response/400');
phutil_require_module('phabricator', 'aphront/response/404');
phutil_require_module('phabricator', 'aphront/response/redirect');
phutil_require_module('phabricator', 'applications/files/controller/base');
phutil_require_module('phabricator', 'applications/files/storage/file');
phutil_require_module('phabricator', 'applications/files/storage/transformed');
+phutil_require_module('phabricator', 'applications/files/transform');
phutil_require_module('phabricator', 'applications/files/uri');
phutil_require_module('phutil', 'utils');
phutil_require_source('PhabricatorFileTransformController.php');
diff --git a/src/applications/files/transform/PhabricatorImageTransformer.php b/src/applications/files/transform/PhabricatorImageTransformer.php
new file mode 100644
index 0000000000..1919e9c4de
--- /dev/null
+++ b/src/applications/files/transform/PhabricatorImageTransformer.php
@@ -0,0 +1,125 @@
+<?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.
+ */
+
+final class PhabricatorImageTransformer {
+
+ public function executeThumbTransform(
+ PhabricatorFile $file,
+ $x,
+ $y) {
+
+ $data = $file->loadFileData();
+ $image = $this->crudelyScaleTo($data, $x, $y);
+
+ return PhabricatorFile::newFromFileData(
+ $image,
+ array(
+ 'name' => 'thumb-'.$file->getName(),
+ ));
+ }
+
+ public function executeProfileTransform(
+ PhabricatorFile $file,
+ $x,
+ $min_y,
+ $max_y) {
+
+ $data = $file->loadFileData();
+ $image = $this->crudelyCropTo($data, $x, $min_y, $max_y);
+
+ return PhabricatorFile::newFromFileData(
+ $image,
+ array(
+ 'name' => 'profile-'.$file->getName(),
+ ));
+ }
+
+ private function crudelyCropTo($data, $x, $min_y, $max_y) {
+ $img = imagecreatefromstring($data);
+ $sx = imagesx($img);
+ $sy = imagesy($img);
+
+ $scaled_y = ($x / $sx) * $sy;
+ if ($scaled_y > $max_y) {
+ // This image is very tall and thin.
+ $scaled_y = $max_y;
+ } else if ($scaled_y < $min_y) {
+ // This image is very short and wide.
+ $scaled_y = $min_y;
+ }
+
+ $img = $this->applyScaleTo(
+ $img,
+ $x,
+ $scaled_y);
+
+ return $this->saveImageDataInAnyFormat($img);
+ }
+
+ /**
+ * Very crudely scale an image up or down to an exact size.
+ */
+ private function crudelyScaleTo($data, $dx, $dy) {
+ $src = imagecreatefromstring($data);
+
+ $dst = $this->applyScaleTo($src, $dx, $dy);
+
+ return $this->saveImageDataInAnyFormat($dst);
+ }
+
+ private function applyScaleTo($src, $dx, $dy) {
+ $x = imagesx($src);
+ $y = imagesy($src);
+
+ $scale = min($x / $dx, $y / $dy);
+ $dst = imagecreatetruecolor($dx, $dy);
+
+ imagecopyresampled(
+ $dst,
+ $src,
+ 0, 0,
+ 0, 0,
+ $dx, $dy,
+ $scale * $dx, $scale * $dy);
+
+ return $dst;
+ }
+
+ private function saveImageDataInAnyFormat($data) {
+ $img = null;
+
+ if (function_exists('imagejpeg')) {
+ ob_start();
+ imagejpeg($data);
+ $img = ob_get_clean();
+ } else if (function_exists('imagepng')) {
+ ob_start();
+ imagepng($data);
+ $img = ob_get_clean();
+ } else if (function_exists('imagegif')) {
+ ob_start();
+ imagegif($data);
+ $img = ob_get_clean();
+ } else {
+ throw new Exception("No image generation functions exist!");
+ }
+
+ return $img;
+ }
+
+}
diff --git a/src/applications/files/transform/__init__.php b/src/applications/files/transform/__init__.php
new file mode 100644
index 0000000000..22c7880540
--- /dev/null
+++ b/src/applications/files/transform/__init__.php
@@ -0,0 +1,12 @@
+<?php
+/**
+ * This file is automatically generated. Lint this module to rebuild it.
+ * @generated
+ */
+
+
+
+phutil_require_module('phabricator', 'applications/files/storage/file');
+
+
+phutil_require_source('PhabricatorImageTransformer.php');
diff --git a/src/applications/maniphest/controller/taskedit/ManiphestTaskEditController.php b/src/applications/maniphest/controller/taskedit/ManiphestTaskEditController.php
index 55ff3a982d..47e474c453 100644
--- a/src/applications/maniphest/controller/taskedit/ManiphestTaskEditController.php
+++ b/src/applications/maniphest/controller/taskedit/ManiphestTaskEditController.php
@@ -1,308 +1,310 @@
<?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 ManiphestTaskEditController extends ManiphestController {
private $id;
public function willProcessRequest(array $data) {
$this->id = idx($data, 'id');
}
public function processRequest() {
$request = $this->getRequest();
$user = $request->getUser();
$files = array();
if ($this->id) {
$task = id(new ManiphestTask())->load($this->id);
if (!$task) {
return new Aphront404Response();
}
} else {
$task = new ManiphestTask();
$task->setPriority(ManiphestTaskPriority::PRIORITY_TRIAGE);
$task->setAuthorPHID($user->getPHID());
// These allow task creation with defaults.
if (!$request->isFormPost()) {
$task->setTitle($request->getStr('title'));
}
$file_phids = $request->getArr('files', array());
if (!$file_phids) {
// Allow a single 'file' key instead, mostly since Mac OS X urlencodes
// square brackets in URLs when passed to 'open', so you can't 'open'
// a URL like '?files[]=xyz' and have PHP interpret it correctly.
$phid = $request->getStr('file');
if ($phid) {
$file_phids = array($phid);
}
}
if ($file_phids) {
$files = id(new PhabricatorFile())->loadAllWhere(
'phid IN (%Ls)',
$file_phids);
}
}
$errors = array();
$e_title = true;
if ($request->isFormPost()) {
$changes = array();
$new_title = $request->getStr('title');
$new_desc = $request->getStr('description');
if ($task->getID()) {
if ($new_title != $task->getTitle()) {
$changes[ManiphestTransactionType::TYPE_TITLE] = $new_title;
}
if ($new_desc != $task->getDescription()) {
$changes[ManiphestTransactionType::TYPE_DESCRIPTION] = $new_desc;
}
} else {
$task->setTitle($new_title);
$task->setDescription($new_desc);
$changes[ManiphestTransactionType::TYPE_STATUS] =
ManiphestTaskStatus::STATUS_OPEN;
}
$owner_tokenizer = $request->getArr('assigned_to');
$owner_phid = reset($owner_tokenizer);
if (!strlen($new_title)) {
$e_title = 'Required';
$errors[] = 'Title is required.';
}
if (!$errors) {
if ($request->getInt('priority') != $task->getPriority()) {
$changes[ManiphestTransactionType::TYPE_PRIORITY] =
$request->getInt('priority');
}
if ($owner_phid != $task->getOwnerPHID()) {
$changes[ManiphestTransactionType::TYPE_OWNER] = $owner_phid;
}
if ($request->getArr('cc') != $task->getCCPHIDs()) {
$changes[ManiphestTransactionType::TYPE_CCS] = $request->getArr('cc');
}
$new_proj_arr = $request->getArr('projects');
$new_proj_arr = array_values($new_proj_arr);
sort($new_proj_arr);
$cur_proj_arr = $task->getProjectPHIDs();
$cur_proj_arr = array_values($cur_proj_arr);
sort($cur_proj_arr);
if ($new_proj_arr != $cur_proj_arr) {
$changes[ManiphestTransactionType::TYPE_PROJECTS] = $new_proj_arr;
}
if ($files) {
$file_map = mpull($files, 'getPHID');
$file_map = array_fill_keys($file_map, true);
$changes[ManiphestTransactionType::TYPE_ATTACH] = array(
PhabricatorPHIDConstants::PHID_TYPE_FILE => $file_map,
);
}
$template = new ManiphestTransaction();
$template->setAuthorPHID($user->getPHID());
$transactions = array();
foreach ($changes as $type => $value) {
$transaction = clone $template;
$transaction->setTransactionType($type);
$transaction->setNewValue($value);
$transactions[] = $transaction;
}
if ($transactions) {
$editor = new ManiphestTransactionEditor();
$editor->applyTransactions($task, $transactions);
}
return id(new AphrontRedirectResponse())
->setURI('/T'.$task->getID());
}
} else {
if (!$task->getID()) {
$task->setCCPHIDs(array(
$user->getPHID(),
));
}
}
$phids = array_merge(
array($task->getOwnerPHID()),
$task->getCCPHIDs(),
$task->getProjectPHIDs());
$phids = array_filter($phids);
$phids = array_unique($phids);
$handles = id(new PhabricatorObjectHandleData($phids))
->loadHandles($phids);
$tvalues = mpull($handles, 'getFullName', 'getPHID');
$error_view = null;
if ($errors) {
$error_view = new AphrontErrorView();
$error_view->setErrors($errors);
$error_view->setTitle('Form Errors');
}
$priority_map = ManiphestTaskPriority::getTaskPriorityMap();
if ($task->getOwnerPHID()) {
$assigned_value = array(
$task->getOwnerPHID() => $handles[$task->getOwnerPHID()]->getFullName(),
);
} else {
$assigned_value = array();
}
if ($task->getCCPHIDs()) {
$cc_value = array_select_keys($tvalues, $task->getCCPHIDs());
} else {
$cc_value = array();
}
if ($task->getProjectPHIDs()) {
$projects_value = array_select_keys($tvalues, $task->getProjectPHIDs());
} else {
$projects_value = array();
}
if ($task->getID()) {
$cancel_uri = '/T'.$task->getID();
$button_name = 'Save Task';
$header_name = 'Edit Task';
} else {
$cancel_uri = '/maniphest/';
$button_name = 'Create Task';
$header_name = 'Create New Task';
}
$project_tokenizer_id = celerity_generate_unique_node_id();
$form = new AphrontFormView();
$form
->setUser($user)
->setAction($request->getRequestURI()->getPath())
->appendChild(
id(new AphrontFormTextAreaControl())
->setLabel('Title')
->setName('title')
->setError($e_title)
->setHeight(AphrontFormTextAreaControl::HEIGHT_VERY_SHORT)
->setValue($task->getTitle()))
->appendChild(
id(new AphrontFormTokenizerControl())
->setLabel('Assigned To')
->setName('assigned_to')
->setValue($assigned_value)
->setDatasource('/typeahead/common/users/')
->setLimit(1))
->appendChild(
id(new AphrontFormTokenizerControl())
->setLabel('CC')
->setName('cc')
->setValue($cc_value)
->setDatasource('/typeahead/common/mailable/'))
->appendChild(
id(new AphrontFormSelectControl())
->setLabel('Priority')
->setName('priority')
->setOptions($priority_map)
->setValue($task->getPriority()))
->appendChild(
id(new AphrontFormTokenizerControl())
->setLabel('Projects')
->setName('projects')
->setValue($projects_value)
->setID($project_tokenizer_id)
->setCaption(
javelin_render_tag(
'a',
array(
- 'href' => '/project/quickcreate/',
+ 'href' => '/project/create/',
'mustcapture' => true,
'sigil' => 'project-create',
),
'Create New Project'))
->setDatasource('/typeahead/common/projects/'));
+ require_celerity_resource('aphront-error-view-css');
+
Javelin::initBehavior('maniphest-project-create', array(
'tokenizerID' => $project_tokenizer_id,
));
if ($files) {
$file_display = array();
foreach ($files as $file) {
$file_display[] = phutil_escape_html($file->getName());
}
$file_display = implode('<br />', $file_display);
$form->appendChild(
id(new AphrontFormMarkupControl())
->setLabel('Files')
->setValue($file_display));
foreach ($files as $ii => $file) {
$form->addHiddenInput('files['.$ii.']', $file->getPHID());
}
}
$form
->appendChild(
id(new AphrontFormTextAreaControl())
->setLabel('Description')
->setName('description')
->setValue($task->getDescription()))
->appendChild(
id(new AphrontFormSubmitControl())
->addCancelButton($cancel_uri)
->setValue($button_name));
$panel = new AphrontPanelView();
$panel->setWidth(AphrontPanelView::WIDTH_FULL);
$panel->setHeader($header_name);
$panel->appendChild($form);
return $this->buildStandardPageResponse(
array(
$error_view,
$panel,
),
array(
'title' => 'Create Task',
));
}
}
diff --git a/src/applications/people/controller/profileedit/PhabricatorPeopleProfileEditController.php b/src/applications/people/controller/profileedit/PhabricatorPeopleProfileEditController.php
index 5b7ec23d31..48e3db955e 100644
--- a/src/applications/people/controller/profileedit/PhabricatorPeopleProfileEditController.php
+++ b/src/applications/people/controller/profileedit/PhabricatorPeopleProfileEditController.php
@@ -1,116 +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 PhabricatorPeopleProfileEditController
extends PhabricatorPeopleController {
public function processRequest() {
$request = $this->getRequest();
$user = $request->getUser();
$profile = id(new PhabricatorUserProfile())->loadOneWhere(
'userPHID = %s',
$user->getPHID());
if (!$profile) {
$profile = new PhabricatorUserProfile();
$profile->setUserPHID($user->getPHID());
}
$errors = array();
if ($request->isFormPost()) {
$profile->setTitle($request->getStr('title'));
$profile->setBlurb($request->getStr('blurb'));
if (!empty($_FILES['image'])) {
$err = idx($_FILES['image'], 'error');
if ($err != UPLOAD_ERR_NO_FILE) {
$file = PhabricatorFile::newFromPHPUpload($_FILES['image']);
$okay = $file->isTransformableImage();
if ($okay) {
- $profile->setProfileImagePHID($file->getPHID());
+ $xformer = new PhabricatorImageTransformer();
+ $xformed = $xformer->executeProfileTransform(
+ $file,
+ $width = 280,
+ $min_height = 140,
+ $max_height = 420);
+ $profile->setProfileImagePHID($xformed->getPHID());
} else {
$errors[] =
'Only valid image files (jpg, jpeg, png or gif) '.
'will be accepted.';
}
}
}
if (!$errors) {
$profile->save();
$response = id(new AphrontRedirectResponse())
->setURI('/p/'.$user->getUsername().'/');
return $response;
}
}
$error_view = null;
if ($errors) {
$error_view = new AphrontErrorView();
$error_view->setTitle('Form Errors');
$error_view->setErrors($errors);
}
$form = new AphrontFormView();
$form
->setUser($request->getUser())
->setAction('/profile/edit/')
->setEncType('multipart/form-data')
->appendChild(
id(new AphrontFormTextControl())
->setLabel('Title')
->setName('title')
->setValue($profile->getTitle())
->setCaption('Serious business title.'))
->appendChild(
'<p class="aphront-form-instructions">Write something about yourself! '.
'Make sure to include <strong>important information</strong> like '.
'your <strong>favorite pokemon</strong> and which '.
'<strong>Starcraft race</strong> you play.</p>')
->appendChild(
id(new AphrontFormTextAreaControl())
->setLabel('Blurb')
->setName('blurb')
->setValue($profile->getBlurb()))
->appendChild(
id(new AphrontFormFileControl())
->setLabel('Change Image')
->setName('image')
->setCaption('Upload a 280px-wide image.'))
->appendChild(
id(new AphrontFormSubmitControl())
->setValue('Save')
->addCancelButton('/p/'.$user->getUsername().'/'));
$panel = new AphrontPanelView();
$panel->setHeader('Edit Profile Details');
$panel->appendChild($form);
$panel->setWidth(AphrontPanelView::WIDTH_FORM);
return $this->buildStandardPageResponse(
array(
$error_view,
$panel,
),
array(
'title' => 'Edit Profile',
));
}
}
diff --git a/src/applications/people/controller/profileedit/__init__.php b/src/applications/people/controller/profileedit/__init__.php
index 0a37dee920..fdfc29408f 100644
--- a/src/applications/people/controller/profileedit/__init__.php
+++ b/src/applications/people/controller/profileedit/__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/redirect');
phutil_require_module('phabricator', 'applications/files/storage/file');
+phutil_require_module('phabricator', 'applications/files/transform');
phutil_require_module('phabricator', 'applications/people/controller/base');
phutil_require_module('phabricator', 'applications/people/storage/profile');
phutil_require_module('phabricator', 'view/form/base');
phutil_require_module('phabricator', 'view/form/control/file');
phutil_require_module('phabricator', 'view/form/control/submit');
phutil_require_module('phabricator', 'view/form/control/text');
phutil_require_module('phabricator', 'view/form/control/textarea');
phutil_require_module('phabricator', 'view/form/error');
phutil_require_module('phabricator', 'view/layout/panel');
phutil_require_module('phutil', 'utils');
-phutil_require_source('PhabricatorPeopleProfileEditController.php');
\ No newline at end of file
+phutil_require_source('PhabricatorPeopleProfileEditController.php');
diff --git a/src/applications/people/controller/settings/PhabricatorUserSettingsController.php b/src/applications/people/controller/settings/PhabricatorUserSettingsController.php
index d00ed87e66..09e43cf39f 100644
--- a/src/applications/people/controller/settings/PhabricatorUserSettingsController.php
+++ b/src/applications/people/controller/settings/PhabricatorUserSettingsController.php
@@ -1,557 +1,561 @@
<?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 PhabricatorUserSettingsController extends PhabricatorPeopleController {
private $page;
private $accountEditable;
public function willProcessRequest(array $data) {
$this->page = idx($data, 'page');
}
public function processRequest() {
$request = $this->getRequest();
$user = $request->getUser();
$pages = array(
'account' => 'Account',
'email' => 'Email',
// 'password' => 'Password',
'arcanist' => 'Arcanist Certificate',
);
$oauth_providers = PhabricatorOAuthProvider::getAllProviders();
foreach ($oauth_providers as $provider) {
if (!$provider->isProviderEnabled()) {
continue;
}
$key = $provider->getProviderKey();
$name = $provider->getProviderName();
$pages[$key] = $name.' Account';
}
if (empty($pages[$this->page])) {
$this->page = key($pages);
}
$account_editable = PhabricatorEnv::getEnvConfig('account.editable');
$this->accountEditable = $account_editable;
$e_realname = true;
$e_email = true;
$errors = array();
if ($request->isFormPost()) {
switch ($this->page) {
case 'email':
if (!$account_editable) {
return new Aphront400Response();
}
$user->setEmail($request->getStr('email'));
if (!strlen($user->getEmail())) {
$errors[] = 'You must enter an e-mail address';
$e_email = 'Required';
}
if (!$errors) {
$user->save();
return id(new AphrontRedirectResponse())
->setURI('/settings/page/email/?saved=true');
}
break;
case 'arcanist':
if (!$request->isDialogFormPost()) {
$dialog = new AphrontDialogView();
$dialog->setUser($user);
$dialog->setTitle('Really regenerate session?');
$dialog->setSubmitURI('/settings/page/arcanist/');
$dialog->addSubmitButton('Regenerate');
$dialog->addCancelbutton('/settings/page/arcanist/');
$dialog->appendChild(
'<p>Really destroy the old certificate? Any established '.
'sessions will be terminated.');
return id(new AphrontDialogResponse())
->setDialog($dialog);
}
$conn = $user->establishConnection('w');
queryfx(
$conn,
'DELETE FROM %T WHERE userPHID = %s AND type LIKE %>',
PhabricatorUser::SESSION_TABLE,
$user->getPHID(),
'conduit');
// This implicitly regenerates the certificate.
$user->setConduitCertificate(null);
$user->save();
return id(new AphrontRedirectResponse())
->setURI('/settings/page/arcanist/?regenerated=true');
break;
case 'account':
if (!$account_editable) {
return new Aphront400Response();
}
if (!empty($_FILES['profile'])) {
$err = idx($_FILES['profile'], 'error');
if ($err != UPLOAD_ERR_NO_FILE) {
$file = PhabricatorFile::newFromPHPUpload($_FILES['profile']);
$okay = $file->isTransformableImage();
-
if ($okay) {
- $user->setProfileImagePHID($file->getPHID());
+ $xformer = new PhabricatorImageTransformer();
+ $xformed = $xformer->executeProfileTransform(
+ $file,
+ $width = 50,
+ $min_height = 50,
+ $max_height = 50);
+ $user->setProfileImagePHID($xformed->getPHID());
} else {
$errors[] =
'Only valid image files (jpg, jpeg, png or gif) '.
'will be accepted.';
}
}
}
$user->setRealName($request->getStr('realname'));
if (!strlen($user->getRealName())) {
$errors[] = 'Real name must be nonempty.';
$e_realname = 'Required';
}
$new_timezone = $request->getStr('timezone');
if (in_array($new_timezone, DateTimeZone::listIdentifiers(), true)) {
$user->setTimezoneIdentifier($new_timezone);
} else {
$errors[] =
'The selected timezone is not a valid timezone.';
}
if (!$errors) {
$user->save();
return id(new AphrontRedirectResponse())
->setURI('/settings/page/account/?saved=true');
}
break;
}
}
switch ($this->page) {
case 'arcanist':
$content = $this->renderArcanistCertificateForm();
break;
case 'account':
$content = $this->renderAccountForm($errors, $e_realname);
break;
case 'email':
$content = $this->renderEmailForm($errors, $e_email);
break;
default:
if (empty($pages[$this->page])) {
return new Aphront404Response();
}
$content = $this->renderOAuthForm($oauth_providers[$this->page]);
break;
}
$sidenav = new AphrontSideNavView();
foreach ($pages as $page => $name) {
$sidenav->addNavItem(
phutil_render_tag(
'a',
array(
'href' => '/settings/page/'.$page.'/',
'class' => ($page == $this->page)
? 'aphront-side-nav-selected'
: null,
),
phutil_escape_html($name)));
}
$sidenav->appendChild($content);
return $this->buildStandardPageResponse(
$sidenav,
array(
'title' => 'Account Settings',
));
}
private function renderArcanistCertificateForm() {
$request = $this->getRequest();
$user = $request->getUser();
if ($request->getStr('regenerated')) {
$notice = new AphrontErrorView();
$notice->setSeverity(AphrontErrorView::SEVERITY_NOTICE);
$notice->setTitle('Certificate Regenerated');
$notice->appendChild(
'<p>Your old certificate has been destroyed and you have been issued '.
'a new certificate. Sessions established under the old certificate '.
'are no longer valid.</p>');
$notice = $notice->render();
} else {
$notice = null;
}
$host = PhabricatorEnv::getEnvConfig('phabricator.base-uri') . 'api/';
$conduit_setting = sprintf(
' %s: {'."\n".
' "user" : %s,'."\n".
' "cert" : %s'."\n".
' }'."\n",
json_encode($host),
json_encode($user->getUserName()),
json_encode($user->getConduitCertificate()));
$cert_form = new AphrontFormView();
$cert_form
->setUser($user)
->appendChild(
'<p class="aphront-form-instructions">Copy and paste the host info '.
'including the certificate into your <tt>~/.arcrc</tt> in the "hosts" '.
'session to enable Arcanist to authenticate against this host.</p>')
->appendChild(
id(new AphrontFormMarkupControl())
->setControlStyle('white-space: pre; font-family: monospace')
->setValue(
'{'."\n".
' ...'."\n".
' "hosts" : {'."\n"))
->appendChild(
id(new AphrontFormTextAreaControl())
->setLabel('Credentials')
->setHeight(AphrontFormTextAreaControl::HEIGHT_SHORT)
->setControlStyle('font-family: monospace')
->setValue($conduit_setting))
->appendChild(
id(new AphrontFormStaticControl())
->setControlStyle('white-space: pre; font-family: monospace')
->setValue(
' }'."\n".
' ...'."\n".
'}'));
$cert = new AphrontPanelView();
$cert->setHeader('Arcanist Certificate');
$cert->appendChild($cert_form);
$cert->setWidth(AphrontPanelView::WIDTH_FORM);
$regen_form = new AphrontFormView();
$regen_form
->setUser($user)
->setAction('/settings/page/arcanist/')
->appendChild(
'<p class="aphront-form-instructions">You can regenerate this '.
'certificate, which will invalidate the old certificate and create '.
'a new one.</p>')
->appendChild(
id(new AphrontFormSubmitControl())
->setValue('Regenerate Certificate'));
$regen = new AphrontPanelView();
$regen->setHeader('Regenerate Certificate');
$regen->appendChild($regen_form);
$regen->setWidth(AphrontPanelView::WIDTH_FORM);
return $notice.$cert->render().$regen->render();
}
private function renderAccountForm(array $errors, $e_realname) {
$request = $this->getRequest();
$user = $request->getUser();
$img_src = PhabricatorFileURI::getViewURIForPHID(
$user->getProfileImagePHID());
$editable = $this->accountEditable;
$notice = null;
if (!$errors) {
if ($request->getStr('saved')) {
$notice = new AphrontErrorView();
$notice->setSeverity(AphrontErrorView::SEVERITY_NOTICE);
$notice->setTitle('Changed Saved');
$notice->appendChild('<p>Your changes have been saved.</p>');
$notice = $notice->render();
}
} else {
$notice = new AphrontErrorView();
$notice->setTitle('Form Errors');
$notice->setErrors($errors);
$notice = $notice->render();
}
$form = new AphrontFormView();
$form
->setUser($user)
->setEncType('multipart/form-data')
->appendChild(
id(new AphrontFormStaticControl())
->setLabel('Username')
->setValue($user->getUsername()))
->appendChild(
id(new AphrontFormTextControl())
->setLabel('Real Name')
->setName('realname')
->setError($e_realname)
->setValue($user->getRealName())
->setDisabled(!$editable))
->appendChild(
id(new AphrontFormMarkupControl())
->setValue('<hr />'))
->appendChild(
id(new AphrontFormMarkupControl())
->setLabel('Profile Image')
->setValue(
phutil_render_tag(
'img',
array(
'src' => $img_src,
))));
if ($editable) {
$timezone_ids = DateTimeZone::listIdentifiers();
$timezone_id_map = array_combine($timezone_ids, $timezone_ids);
$form
->appendChild(
id(new AphrontFormFileControl())
->setLabel('Change Image')
- ->setName('profile')
- ->setCaption('Upload a 50x50px image.'))
+ ->setName('profile'))
->appendChild(
id(new AphrontFormMarkupControl())
->setValue('<hr />'))
->appendChild(
id(new AphrontFormSelectControl())
->setLabel('Timezone')
->setName('timezone')
->setOptions($timezone_id_map)
->setValue($user->getTimezoneIdentifier()))
->appendChild(
id(new AphrontFormMarkupControl())
->setValue('<hr />'))
->appendChild(
id(new AphrontFormSubmitControl())
->setValue('Save'));
}
$panel = new AphrontPanelView();
$panel->setHeader('Profile Settings');
$panel->setWidth(AphrontPanelView::WIDTH_FORM);
$panel->appendChild($form);
return $notice.$panel->render();
}
private function renderEmailForm(array $errors, $e_email) {
$request = $this->getRequest();
$user = $request->getUser();
$editable = $this->accountEditable;
$notice = null;
if (!$errors) {
if ($request->getStr('saved')) {
$notice = new AphrontErrorView();
$notice->setSeverity(AphrontErrorView::SEVERITY_NOTICE);
$notice->setTitle('Changed Saved');
$notice->appendChild('<p>Your changes have been saved.</p>');
$notice = $notice->render();
}
} else {
$notice = new AphrontErrorView();
$notice->setTitle('Form Errors');
$notice->setErrors($errors);
$notice = $notice->render();
}
$form = new AphrontFormView();
$form
->setUser($user)
->appendChild(
id(new AphrontFormTextControl())
->setLabel('Email')
->setName('email')
->setDisabled(!$editable)
->setCaption(
'Note: there is no email validation yet; double-check your '.
'typing.')
->setValue($user->getEmail())
->setError($e_email));
if ($editable) {
$form
->appendChild(
id(new AphrontFormSubmitControl())
->setValue('Save'));
}
$panel = new AphrontPanelView();
$panel->setHeader('Email Settings');
$panel->setWidth(AphrontPanelView::WIDTH_FORM);
$panel->appendChild($form);
return $notice.$panel->render();
}
private function renderOAuthForm(PhabricatorOAuthProvider $provider) {
$request = $this->getRequest();
$user = $request->getUser();
$notice = null;
$provider_name = $provider->getProviderName();
$provider_key = $provider->getProviderKey();
$oauth_info = id(new PhabricatorUserOAuthInfo())->loadOneWhere(
'userID = %d AND oauthProvider = %s',
$user->getID(),
$provider->getProviderKey());
$form = new AphrontFormView();
$form
->setUser($user);
$forms = array();
$forms[] = $form;
if (!$oauth_info) {
$form
->appendChild(
'<p class="aphront-form-instructions">There is currently no '.
$provider_name.' account linked to your Phabricator account. You '.
'can link an account, which will allow you to use it to log into '.
'Phabricator.</p>');
switch ($provider_key) {
case PhabricatorOAuthProvider::PROVIDER_GITHUB:
$form->appendChild(
'<p class="aphront-form-instructions">Additionally, you must '.
'link your Github account before Phabricator can access any '.
'information about hosted repositories.</p>');
break;
}
$auth_uri = $provider->getAuthURI();
$client_id = $provider->getClientID();
$redirect_uri = $provider->getRedirectURI();
$form
->setAction($auth_uri)
->setMethod('GET')
->addHiddenInput('redirect_uri', $redirect_uri)
->addHiddenInput('client_id', $client_id)
->appendChild(
id(new AphrontFormSubmitControl())
->setValue('Link '.$provider_name." Account \xC2\xBB"));
} else {
$form
->appendChild(
'<p class="aphront-form-instructions">Your account is linked with '.
'a '.$provider_name.' account. You may use your '.$provider_name.' '.
'credentials to log into Phabricator.</p>')
->appendChild(
id(new AphrontFormStaticControl())
->setLabel($provider_name.' ID')
->setValue($oauth_info->getOAuthUID()))
->appendChild(
id(new AphrontFormStaticControl())
->setLabel($provider_name.' Name')
->setValue($oauth_info->getAccountName()))
->appendChild(
id(new AphrontFormStaticControl())
->setLabel($provider_name.' URI')
->setValue($oauth_info->getAccountURI()));
if (!$provider->isProviderLinkPermanent()) {
$unlink = 'Unlink '.$provider_name.' Account';
$unlink_form = new AphrontFormView();
$unlink_form
->setUser($user)
->appendChild(
'<p class="aphront-form-instructions">You may unlink this account '.
'from your '.$provider_name.' account. This will prevent you from '.
'logging in with your '.$provider_name.' credentials.</p>')
->appendChild(
id(new AphrontFormSubmitControl())
->addCancelButton('/oauth/'.$provider_key.'/unlink/', $unlink));
$forms['Unlink Account'] = $unlink_form;
}
$expires = $oauth_info->getTokenExpires();
if ($expires) {
if ($expires <= time()) {
$expires = "Expired";
} else {
$expires = phabricator_format_timestamp($expires);
}
} else {
$expires = 'No Information Available';
}
$scope = $oauth_info->getTokenScope();
if (!$scope) {
$scope = 'No Information Available';
}
$status = $oauth_info->getTokenStatus();
$status = PhabricatorUserOAuthInfo::getReadableTokenStatus($status);
$token_form = new AphrontFormView();
$token_form
->setUser($user)
->appendChild(
'<p class="aphront-from-instructions">insert rap about tokens</p>')
->appendChild(
id(new AphrontFormStaticControl())
->setLabel('Token Status')
->setValue($status))
->appendChild(
id(new AphrontFormStaticControl())
->setLabel('Expires')
->setValue($expires))
->appendChild(
id(new AphrontFormStaticControl())
->setLabel('Scope')
->setValue($scope));
$forms['Account Token Information'] = $token_form;
}
$panel = new AphrontPanelView();
$panel->setHeader($provider_name.' Account Settings');
$panel->setWidth(AphrontPanelView::WIDTH_FORM);
foreach ($forms as $name => $form) {
if ($name) {
$panel->appendChild('<br /><br /><h1>'.$name.'</h1>');
}
$panel->appendChild($form);
}
return $notice.$panel->render();
}
}
diff --git a/src/applications/people/controller/settings/__init__.php b/src/applications/people/controller/settings/__init__.php
index 1a952ff9c4..b85ec56b52 100644
--- a/src/applications/people/controller/settings/__init__.php
+++ b/src/applications/people/controller/settings/__init__.php
@@ -1,39 +1,40 @@
<?php
/**
* This file is automatically generated. Lint this module to rebuild it.
* @generated
*/
phutil_require_module('phabricator', 'aphront/response/400');
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/auth/oauth/provider/base');
phutil_require_module('phabricator', 'applications/files/storage/file');
+phutil_require_module('phabricator', 'applications/files/transform');
phutil_require_module('phabricator', 'applications/files/uri');
phutil_require_module('phabricator', 'applications/people/controller/base');
phutil_require_module('phabricator', 'applications/people/storage/user');
phutil_require_module('phabricator', 'applications/people/storage/useroauthinfo');
phutil_require_module('phabricator', 'infrastructure/env');
phutil_require_module('phabricator', 'storage/queryfx');
phutil_require_module('phabricator', 'view/dialog');
phutil_require_module('phabricator', 'view/form/base');
phutil_require_module('phabricator', 'view/form/control/file');
phutil_require_module('phabricator', 'view/form/control/markup');
phutil_require_module('phabricator', 'view/form/control/select');
phutil_require_module('phabricator', 'view/form/control/static');
phutil_require_module('phabricator', 'view/form/control/submit');
phutil_require_module('phabricator', 'view/form/control/text');
phutil_require_module('phabricator', 'view/form/control/textarea');
phutil_require_module('phabricator', 'view/form/error');
phutil_require_module('phabricator', 'view/layout/panel');
phutil_require_module('phabricator', 'view/layout/sidenav');
phutil_require_module('phabricator', 'view/utils');
phutil_require_module('phutil', 'markup');
phutil_require_module('phutil', 'utils');
phutil_require_source('PhabricatorUserSettingsController.php');
diff --git a/src/applications/project/controller/quickcreate/PhabricatorProjectQuickCreateController.php b/src/applications/project/controller/create/PhabricatorProjectCreateController.php
similarity index 51%
rename from src/applications/project/controller/quickcreate/PhabricatorProjectQuickCreateController.php
rename to src/applications/project/controller/create/PhabricatorProjectCreateController.php
index e4e2c1796e..f4c8560f12 100644
--- a/src/applications/project/controller/quickcreate/PhabricatorProjectQuickCreateController.php
+++ b/src/applications/project/controller/create/PhabricatorProjectCreateController.php
@@ -1,93 +1,141 @@
<?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 PhabricatorProjectQuickCreateController
+class PhabricatorProjectCreateController
extends PhabricatorProjectController {
public function processRequest() {
$request = $this->getRequest();
$user = $request->getUser();
$project = new PhabricatorProject();
$project->setAuthorPHID($user->getPHID());
$profile = new PhabricatorProjectProfile();
- $options = PhabricatorProjectStatus::getStatusMap();
$e_name = true;
$errors = array();
if ($request->isFormPost()) {
$project->setName($request->getStr('name'));
+ $project->setStatus(PhabricatorProjectStatus::ONGOING);
+
$profile->setBlurb($request->getStr('blurb'));
if (!strlen($project->getName())) {
$e_name = 'Required';
$errors[] = 'Project name is required.';
} else {
$e_name = null;
}
if (!$errors) {
$project->save();
$profile->setProjectPHID($project->getPHID());
$profile->save();
- return id(new AphrontAjaxResponse())
- ->setContent(array(
- 'phid' => $project->getPHID(),
- 'name' => $project->getName(),
- ));
+ id(new PhabricatorProjectAffiliation())
+ ->setUserPHID($user->getPHID())
+ ->setProjectPHID($project->getPHID())
+ ->setRole('Owner')
+ ->setIsOwner(true)
+ ->save();
+
+ if ($request->isAjax()) {
+ return id(new AphrontAjaxResponse())
+ ->setContent(array(
+ 'phid' => $project->getPHID(),
+ 'name' => $project->getName(),
+ ));
+ } else {
+ return id(new AphrontRedirectResponse())
+ ->setURI('/project/view/'.$project->getID().'/');
+ }
}
}
$error_view = null;
if ($errors) {
$error_view = new AphrontErrorView();
$error_view->setTitle('Form Errors');
- $error_view->setWidth(AphrontErrorView::WIDTH_DIALOG);
$error_view->setErrors($errors);
}
- $form = id(new AphrontFormLayoutView())
+ if ($request->isAjax()) {
+ $form = new AphrontFormLayoutView();
+ } else {
+ $form = new AphrontFormView();
+ $form->setUser($user);
+ }
+
+ $form
->appendChild(
id(new AphrontFormTextControl())
->setLabel('Name')
->setName('name')
->setValue($project->getName())
->setError($e_name))
->appendChild(
id(new AphrontFormTextAreaControl())
->setLabel('Blurb')
->setName('blurb')
->setHeight(AphrontFormTextAreaControl::HEIGHT_VERY_SHORT)
->setValue($profile->getBlurb()));
- $dialog = id(new AphrontDialogView())
- ->setUser($user)
- ->setWidth(AphrontDialogView::WIDTH_FORM)
- ->setTitle('Create a New Project')
- ->appendChild($error_view)
- ->appendChild($form)
- ->addSubmitButton('Create Project')
- ->addCancelButton('/project/');
+ if ($request->isAjax()) {
+
+ if ($error_view) {
+ $error_view->setWidth(AphrontErrorView::WIDTH_DIALOG);
+ }
- return id(new AphrontDialogResponse())->setDialog($dialog);
+ $dialog = id(new AphrontDialogView())
+ ->setUser($user)
+ ->setWidth(AphrontDialogView::WIDTH_FORM)
+ ->setTitle('Create a New Project')
+ ->appendChild($error_view)
+ ->appendChild($form)
+ ->addSubmitButton('Create Project')
+ ->addCancelButton('/project/');
+
+ return id(new AphrontDialogResponse())->setDialog($dialog);
+ } else {
+
+ $form
+ ->appendChild(
+ id(new AphrontFormSubmitControl())
+ ->setValue('Create')
+ ->addCancelButton('/project/'));
+
+ $panel = new AphrontPanelView();
+ $panel
+ ->setWidth(AphrontPanelView::WIDTH_FORM)
+ ->setHeader('Create a New Project')
+ ->appendChild($form);
+
+ return $this->buildStandardPageResponse(
+ array(
+ $error_view,
+ $panel,
+ ),
+ array(
+ 'title' => 'Create new Project',
+ ));
+ }
}
}
diff --git a/src/applications/project/controller/quickcreate/__init__.php b/src/applications/project/controller/create/__init__.php
similarity index 69%
rename from src/applications/project/controller/quickcreate/__init__.php
rename to src/applications/project/controller/create/__init__.php
index 3e33f41148..e9d5874a69 100644
--- a/src/applications/project/controller/quickcreate/__init__.php
+++ b/src/applications/project/controller/create/__init__.php
@@ -1,24 +1,29 @@
<?php
/**
* This file is automatically generated. Lint this module to rebuild it.
* @generated
*/
phutil_require_module('phabricator', 'aphront/response/ajax');
phutil_require_module('phabricator', 'aphront/response/dialog');
+phutil_require_module('phabricator', 'aphront/response/redirect');
phutil_require_module('phabricator', 'applications/project/constants/status');
phutil_require_module('phabricator', 'applications/project/controller/base');
+phutil_require_module('phabricator', 'applications/project/storage/affiliation');
phutil_require_module('phabricator', 'applications/project/storage/profile');
phutil_require_module('phabricator', 'applications/project/storage/project');
phutil_require_module('phabricator', 'view/dialog');
+phutil_require_module('phabricator', 'view/form/base');
+phutil_require_module('phabricator', 'view/form/control/submit');
phutil_require_module('phabricator', 'view/form/control/text');
phutil_require_module('phabricator', 'view/form/control/textarea');
phutil_require_module('phabricator', 'view/form/error');
phutil_require_module('phabricator', 'view/form/layout');
+phutil_require_module('phabricator', 'view/layout/panel');
phutil_require_module('phutil', 'utils');
-phutil_require_source('PhabricatorProjectQuickCreateController.php');
+phutil_require_source('PhabricatorProjectCreateController.php');
diff --git a/src/applications/project/controller/editaffiliation/PhabricatorProjectAffiliationEditController.php b/src/applications/project/controller/editaffiliation/PhabricatorProjectAffiliationEditController.php
index 4dffe20957..9c53b63e35 100644
--- a/src/applications/project/controller/editaffiliation/PhabricatorProjectAffiliationEditController.php
+++ b/src/applications/project/controller/editaffiliation/PhabricatorProjectAffiliationEditController.php
@@ -1,102 +1,107 @@
<?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 PhabricatorProjectAffiliationEditController
extends PhabricatorProjectController {
private $id;
public function willProcessRequest(array $data) {
$this->id = $data['id'];
}
public function processRequest() {
$request = $this->getRequest();
$user = $request->getUser();
$project = id(new PhabricatorProject())->load($this->id);
if (!$project) {
return new Aphront404Response();
}
$affiliation = id(new PhabricatorProjectAffiliation())->loadOneWhere(
'projectPHID = %s AND userPHID = %s',
$project->getPHID(),
$user->getPHID());
if (!$affiliation) {
$affiliation = new PhabricatorProjectAffiliation();
$affiliation->setUserPHID($user->getPHID());
$affiliation->setProjectPHID($project->getPHID());
}
if ($request->isFormPost()) {
$affiliation->setRole($request->getStr('role'));
$affiliation->setStatus($request->getStr('status'));
if (!strlen($affiliation->getRole())) {
if ($affiliation->getID()) {
- $affiliation->delete();
+ if ($affiliation->getIsOwner()) {
+ $affiliation->setRole('Owner');
+ $affiliation->save();
+ } else {
+ $affiliation->delete();
+ }
}
} else {
$affiliation->save();
}
return id(new AphrontRedirectResponse())
->setURI('/project/view/'.$project->getID().'/');
}
$status_options = array(
'' => 'Current',
'former' => 'Former',
);
$form = new AphrontFormView();
$form
->setUser($user)
->setAction('/project/affiliation/'.$project->getID().'/')
->appendChild(
id(new AphrontFormTextControl())
->setLabel('Role')
->setName('role')
->setValue($affiliation->getRole()))
->appendChild(
id(new AphrontFormSelectControl())
->setLabel('Status')
->setName('status')
->setOptions($status_options)
->setValue($affiliation->getStatus()))
->appendChild(
id(new AphrontFormSubmitControl())
->addCancelButton('/project/view/'.$project->getID().'/')
->setValue('Save'));
$panel = new AphrontPanelView();
$panel->setHeader('Edit Project Affiliation');
$panel->setWidth(AphrontPanelView::WIDTH_FORM);
$panel->appendChild($form);
return $this->buildStandardPageResponse(
$panel,
array(
'title' => 'Edit Project Affiliation',
));
}
}
diff --git a/src/applications/project/controller/list/PhabricatorProjectListController.php b/src/applications/project/controller/list/PhabricatorProjectListController.php
index 852e5868c7..ba825511ee 100644
--- a/src/applications/project/controller/list/PhabricatorProjectListController.php
+++ b/src/applications/project/controller/list/PhabricatorProjectListController.php
@@ -1,146 +1,146 @@
<?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 PhabricatorProjectListController
extends PhabricatorProjectController {
public function processRequest() {
$projects = id(new PhabricatorProject())->loadAllWhere(
'1 = 1 ORDER BY id DESC limit 100');
$project_phids = mpull($projects, 'getPHID');
$profiles = array();
if ($projects) {
$profiles = id(new PhabricatorProjectProfile())->loadAllWhere(
'projectPHID in (%Ls)',
$project_phids);
$profiles = mpull($profiles, null, 'getProjectPHID');
}
$affil_groups = array();
if ($projects) {
$affil_groups = PhabricatorProjectAffiliation::loadAllForProjectPHIDs(
$project_phids);
}
$author_phids = mpull($projects, 'getAuthorPHID');
$handles = id(new PhabricatorObjectHandleData($author_phids))
->loadHandles();
$rows = array();
foreach ($projects as $project) {
$profile = $profiles[$project->getPHID()];
$affiliations = $affil_groups[$project->getPHID()];
$documents = new PhabricatorProjectTransactionSearch($project->getPHID());
// search all open documents by default
$documents->setSearchOptions();
$documents = $documents->executeSearch();
$documents_types = igroup($documents, 'documentType');
$tasks = idx(
$documents_types,
PhabricatorPHIDConstants::PHID_TYPE_TASK);
$tasks_amount = count($tasks);
// TODO: set up a relationship between the project and the arcanist's
// project, to be able get the revisions.
$revisions = idx(
$documents_types,
PhabricatorPHIDConstants::PHID_TYPE_DREV);
$revisions_amount = count($revisions);
$population = count($affiliations);
$status = PhabricatorProjectStatus::getNameForStatus(
$project->getStatus());
$blurb = nonempty(
$profile->getBlurb(),
'Oops!, nothing is known about this elusive project.');
$blurb = $this->textWrap($blurb, $columns = 100);
$rows[] = array(
phutil_escape_html($project->getName()),
phutil_escape_html($blurb),
$handles[$project->getAuthorPHID()]->renderLink(),
phutil_escape_html($population),
phutil_escape_html($status),
phutil_escape_html($tasks_amount),
// phutil_escape_html($revisions_amount),
phutil_render_tag(
'a',
array(
'class' => 'small grey button',
'href' => '/project/view/'.$project->getID().'/',
),
'View Project Profile'),
);
}
$table = new AphrontTableView($rows);
$table->setHeaders(
array(
'Project',
'Blurb',
'Mastermind',
'Population',
'Status',
'Open Tasks',
// 'Open Revisions',
'',
));
$table->setColumnClasses(
array(
'pri',
'wide',
'',
'right',
'pri',
'right',
// 'right',
'action',
));
$panel = new AphrontPanelView();
$panel->appendChild($table);
$panel->setHeader('Project');
- $panel->setCreateButton('Create New Project', '/project/edit/');
+ $panel->setCreateButton('Create New Project', '/project/create/');
return $this->buildStandardPageResponse(
$panel,
array(
'title' => 'Projects',
));
}
private function textWrap($text, $length) {
if (strlen($text) <= $length) {
return $text;
} else {
// TODO: perhaps this could be improved, adding the ability to get the
// last letter and suppress it, if it is one of [(,:; ,etc.
// making "blurb" looks a little bit better. :)
$wrapped = wordwrap($text, $length, '__#END#__');
$end_position = strpos($wrapped, '__#END#__');
$wrapped = substr($text, 0, $end_position).'...';
return $wrapped;
}
}
}
diff --git a/src/applications/project/controller/profileedit/PhabricatorProjectProfileEditController.php b/src/applications/project/controller/profileedit/PhabricatorProjectProfileEditController.php
index 20cc2dfd6e..cef8edb283 100644
--- a/src/applications/project/controller/profileedit/PhabricatorProjectProfileEditController.php
+++ b/src/applications/project/controller/profileedit/PhabricatorProjectProfileEditController.php
@@ -1,151 +1,143 @@
<?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 PhabricatorProjectProfileEditController
extends PhabricatorProjectController {
- private $id;
-
public function willProcessRequest(array $data) {
- $this->id = idx($data, 'id');
+ $this->id = $data['id'];
}
public function processRequest() {
$request = $this->getRequest();
$user = $request->getUser();
- if ($this->id) {
- $project = id(new PhabricatorProject())->load($this->id);
- if (!$project) {
- return new Aphront404Response();
- }
- $profile = $project->loadProfile();
- } else {
- $project = new PhabricatorProject();
- $project->setAuthorPHID($user->getPHID());
+ $project = id(new PhabricatorProject())->load($this->id);
+ if (!$project) {
+ return new Aphront404Response();
}
+ $profile = $project->loadProfile();
if (empty($profile)) {
$profile = new PhabricatorProjectProfile();
}
$options = PhabricatorProjectStatus::getStatusMap();
$e_name = true;
$errors = array();
if ($request->isFormPost()) {
$project->setName($request->getStr('name'));
$project->setStatus($request->getStr('status'));
$profile->setBlurb($request->getStr('blurb'));
if (!strlen($project->getName())) {
$e_name = 'Required';
$errors[] = 'Project name is required.';
} else {
$e_name = null;
}
if (!empty($_FILES['image'])) {
$err = idx($_FILES['image'], 'error');
if ($err != UPLOAD_ERR_NO_FILE) {
$file = PhabricatorFile::newFromPHPUpload($_FILES['image']);
$okay = $file->isTransformableImage();
if ($okay) {
- $profile->setProfileImagePHID($file->getPHID());
+ $xformer = new PhabricatorImageTransformer();
+ $xformed = $xformer->executeProfileTransform(
+ $file,
+ $width = 280,
+ $min_height = 140,
+ $max_height = 420);
+ $profile->setProfileImagePHID($xformed->getPHID());
} else {
$errors[] =
'Only valid image files (jpg, jpeg, png or gif) '.
'will be accepted.';
}
}
}
if (!$errors) {
$project->save();
$profile->setProjectPHID($project->getPHID());
$profile->save();
return id(new AphrontRedirectResponse())
->setURI('/project/view/'.$project->getID().'/');
}
}
$error_view = null;
if ($errors) {
$error_view = new AphrontErrorView();
$error_view->setTitle('Form Errors');
$error_view->setErrors($errors);
}
- if ($project->getID()) {
- $header_name = 'Edit Project';
- $title = 'Edit Project';
- $action = '/project/edit/'.$project->getID().'/';
- } else {
- $header_name = 'Create Project';
- $title = 'Create Project';
- $action = '/project/edit/';
- }
+ $header_name = 'Edit Project';
+ $title = 'Edit Project';
+ $action = '/project/edit/'.$project->getID().'/';
$form = new AphrontFormView();
$form
->setUser($user)
->setAction($action)
->setEncType('multipart/form-data')
->appendChild(
id(new AphrontFormTextControl())
->setLabel('Name')
->setName('name')
->setValue($project->getName())
->setError($e_name))
->appendChild(
id(new AphrontFormSelectControl())
->setLabel('Project Status')
->setName('status')
->setOptions($options)
->setValue($project->getStatus()))
->appendChild(
id(new AphrontFormTextAreaControl())
->setLabel('Blurb')
->setName('blurb')
->setValue($profile->getBlurb()))
->appendChild(
id(new AphrontFormFileControl())
->setLabel('Change Image')
- ->setName('image')
- ->setCaption('Upload a 280px-wide image.'))
+ ->setName('image'))
->appendChild(
id(new AphrontFormSubmitControl())
->addCancelButton('/project/view/'.$project->getID().'/')
->setValue('Save'));
$panel = new AphrontPanelView();
$panel->setHeader($header_name);
$panel->setWidth(AphrontPanelView::WIDTH_FORM);
$panel->appendChild($form);
return $this->buildStandardPageResponse(
array(
$error_view,
$panel,
),
array(
'title' => $title,
));
}
}
diff --git a/src/applications/project/controller/profileedit/__init__.php b/src/applications/project/controller/profileedit/__init__.php
index ae3c1e153e..a03f8883d2 100644
--- a/src/applications/project/controller/profileedit/__init__.php
+++ b/src/applications/project/controller/profileedit/__init__.php
@@ -1,28 +1,29 @@
<?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/files/transform');
phutil_require_module('phabricator', 'applications/project/constants/status');
phutil_require_module('phabricator', 'applications/project/controller/base');
phutil_require_module('phabricator', 'applications/project/storage/profile');
phutil_require_module('phabricator', 'applications/project/storage/project');
phutil_require_module('phabricator', 'view/form/base');
phutil_require_module('phabricator', 'view/form/control/file');
phutil_require_module('phabricator', 'view/form/control/select');
phutil_require_module('phabricator', 'view/form/control/submit');
phutil_require_module('phabricator', 'view/form/control/text');
phutil_require_module('phabricator', 'view/form/control/textarea');
phutil_require_module('phabricator', 'view/form/error');
phutil_require_module('phabricator', 'view/layout/panel');
phutil_require_module('phutil', 'utils');
phutil_require_source('PhabricatorProjectProfileEditController.php');
diff --git a/src/applications/project/storage/affiliation/PhabricatorProjectAffiliation.php b/src/applications/project/storage/affiliation/PhabricatorProjectAffiliation.php
index 23c73254a8..7dc819792b 100644
--- a/src/applications/project/storage/affiliation/PhabricatorProjectAffiliation.php
+++ b/src/applications/project/storage/affiliation/PhabricatorProjectAffiliation.php
@@ -1,39 +1,40 @@
<?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 PhabricatorProjectAffiliation extends PhabricatorProjectDAO {
protected $projectPHID;
protected $userPHID;
protected $role;
- protected $status;
+ protected $status = '';
+ protected $isOwner = 0;
public static function loadAllForProjectPHIDs($phids) {
if (!$phids) {
return array();
}
$default = array_fill_keys($phids, array());
$affiliations = id(new PhabricatorProjectAffiliation())->loadAllWhere(
'projectPHID IN (%Ls) ORDER BY IF(status = "former", 1, 0), dateCreated',
$phids);
return mgroup($affiliations, 'getProjectPHID') + $default;
}
}

File Metadata

Mime Type
text/x-diff
Expires
Fri, Oct 31, 6:34 AM (14 h, 44 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
312031
Default Alt Text
(159 KB)

Event Timeline