diff --git a/scripts/daemon/run_daemon.php b/scripts/__init_env__.php old mode 100755 new mode 100644 similarity index 71% copy from scripts/daemon/run_daemon.php copy to scripts/__init_env__.php index b3cf97ab4d..88a278d5e0 --- a/scripts/daemon/run_daemon.php +++ b/scripts/__init_env__.php @@ -1,38 +1,31 @@ -#!/usr/bin/env php run(); diff --git a/scripts/__init_script__.php b/scripts/__init_script__.php index bdf6abeb83..a69ac9a5a8 100644 --- a/scripts/__init_script__.php +++ b/scripts/__init_script__.php @@ -1,34 +1,32 @@ run(); diff --git a/scripts/search/reindex_everything.php b/scripts/search/reindex_everything.php new file mode 100755 index 0000000000..112581c0d8 --- /dev/null +++ b/scripts/search/reindex_everything.php @@ -0,0 +1,53 @@ +#!/usr/bin/env php +loadAll(); +$count = count($revs); +echo "Reindexing {$count} revisions"; +foreach ($revs as $rev) { + PhabricatorSearchDifferentialIndexer::indexRevision($rev); + echo '.'; +} +echo "\n"; + +echo "Loading tasks...\n"; +$tasks = id(new ManiphestTask())->loadAll(); +$count = count($tasks); +echo "Reindexing {$count} tasks"; +foreach ($tasks as $task) { + PhabricatorSearchManiphestIndexer::indexTask($task); + echo '.'; +} +echo "\n"; +echo "Done.\n"; + diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php index f7ad64232e..8f89863e8d 100644 --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -1,454 +1,480 @@ array( 'Aphront400Response' => 'aphront/response/400', 'Aphront404Response' => 'aphront/response/404', 'AphrontAjaxResponse' => 'aphront/response/ajax', 'AphrontApplicationConfiguration' => 'aphront/applicationconfiguration', 'AphrontController' => 'aphront/controller', 'AphrontDatabaseConnection' => 'storage/connection/base', 'AphrontDefaultApplicationConfiguration' => 'aphront/default/configuration', 'AphrontDefaultApplicationController' => 'aphront/default/controller', 'AphrontDialogResponse' => 'aphront/response/dialog', 'AphrontDialogView' => 'view/dialog', 'AphrontErrorView' => 'view/form/error', 'AphrontException' => 'aphront/exception/base', 'AphrontFileResponse' => 'aphront/response/file', 'AphrontFormCheckboxControl' => 'view/form/control/checkbox', 'AphrontFormControl' => 'view/form/control/base', 'AphrontFormDividerControl' => 'view/form/control/divider', 'AphrontFormFileControl' => 'view/form/control/file', 'AphrontFormMarkupControl' => 'view/form/control/markup', 'AphrontFormPasswordControl' => 'view/form/control/password', 'AphrontFormRecaptchaControl' => 'view/form/control/recaptcha', 'AphrontFormSelectControl' => 'view/form/control/select', 'AphrontFormStaticControl' => 'view/form/control/static', 'AphrontFormSubmitControl' => 'view/form/control/submit', 'AphrontFormTextAreaControl' => 'view/form/control/textarea', 'AphrontFormTextControl' => 'view/form/control/text', 'AphrontFormTokenizerControl' => 'view/form/control/tokenizer', 'AphrontFormView' => 'view/form/base', 'AphrontMySQLDatabaseConnection' => 'storage/connection/mysql', 'AphrontNullView' => 'view/null', 'AphrontPageView' => 'view/page/base', 'AphrontPanelView' => 'view/layout/panel', 'AphrontQueryConnectionException' => 'storage/exception/connection', 'AphrontQueryConnectionLostException' => 'storage/exception/connectionlost', 'AphrontQueryCountException' => 'storage/exception/count', 'AphrontQueryDuplicateKeyException' => 'storage/exception/duplicatekey', 'AphrontQueryException' => 'storage/exception/base', 'AphrontQueryObjectMissingException' => 'storage/exception/objectmissing', 'AphrontQueryParameterException' => 'storage/exception/parameter', 'AphrontQueryRecoverableException' => 'storage/exception/recoverable', 'AphrontRedirectException' => 'aphront/exception/redirect', 'AphrontRedirectResponse' => 'aphront/response/redirect', 'AphrontRequest' => 'aphront/request', 'AphrontRequestFailureView' => 'view/page/failure', 'AphrontResponse' => 'aphront/response/base', 'AphrontSideNavView' => 'view/layout/sidenav', 'AphrontTableView' => 'view/control/table', 'AphrontURIMapper' => 'aphront/mapper', 'AphrontView' => 'view/base', 'AphrontWebpageResponse' => 'aphront/response/webpage', 'CelerityAPI' => 'infrastructure/celerity/api', 'CelerityResourceController' => 'infrastructure/celerity/controller', 'CelerityResourceMap' => 'infrastructure/celerity/map', 'CelerityStaticResourceResponse' => 'infrastructure/celerity/response', 'ConduitAPIMethod' => 'applications/conduit/method/base', 'ConduitAPIRequest' => 'applications/conduit/protocol/request', 'ConduitAPI_conduit_connect_Method' => 'applications/conduit/method/conduit/connect', 'ConduitAPI_differential_creatediff_Method' => 'applications/conduit/method/differential/creatediff', 'ConduitAPI_differential_createrevision_Method' => 'applications/conduit/method/differential/createrevision', 'ConduitAPI_differential_find_Method' => 'applications/conduit/method/differential/find', 'ConduitAPI_differential_getcommitmessage_Method' => 'applications/conduit/method/differential/getcommitmessage', 'ConduitAPI_differential_markcommitted_Method' => 'applications/conduit/method/differential/markcommitted', 'ConduitAPI_differential_parsecommitmessage_Method' => 'applications/conduit/method/differential/parsecommitmessage', 'ConduitAPI_differential_setdiffproperty_Method' => 'applications/conduit/method/differential/setdiffproperty', 'ConduitAPI_differential_updaterevision_Method' => 'applications/conduit/method/differential/updaterevision', 'ConduitAPI_file_upload_Method' => 'applications/conduit/method/file/upload', 'ConduitAPI_user_find_Method' => 'applications/conduit/method/user/find', 'ConduitException' => 'applications/conduit/protocol/exception', 'DarkConsole' => 'aphront/console/api', 'DarkConsoleConfigPlugin' => 'aphront/console/plugin/config', 'DarkConsoleController' => 'aphront/console/controller', 'DarkConsoleCore' => 'aphront/console/core', 'DarkConsoleErrorLogPlugin' => 'aphront/console/plugin/errorlog', 'DarkConsoleErrorLogPluginAPI' => 'aphront/console/plugin/errorlog/api', 'DarkConsolePlugin' => 'aphront/console/plugin/base', 'DarkConsoleRequestPlugin' => 'aphront/console/plugin/request', 'DarkConsoleServicesPlugin' => 'aphront/console/plugin/services', 'DarkConsoleServicesPluginAPI' => 'aphront/console/plugin/services/api', 'DarkConsoleXHProfPlugin' => 'aphront/console/plugin/xhprof', 'DarkConsoleXHProfPluginAPI' => 'aphront/console/plugin/xhprof/api', 'DifferentialAction' => 'applications/differential/constants/action', 'DifferentialAddCommentView' => 'applications/differential/view/addcomment', 'DifferentialCCWelcomeMail' => 'applications/differential/mail/ccwelcome', 'DifferentialChangeType' => 'applications/differential/constants/changetype', 'DifferentialChangeset' => 'applications/differential/storage/changeset', 'DifferentialChangesetDetailView' => 'applications/differential/view/changesetdetailview', 'DifferentialChangesetListView' => 'applications/differential/view/changesetlistview', 'DifferentialChangesetParser' => 'applications/differential/parser/changeset', 'DifferentialChangesetViewController' => 'applications/differential/controller/changesetview', 'DifferentialComment' => 'applications/differential/storage/comment', 'DifferentialCommentEditor' => 'applications/differential/editor/comment', 'DifferentialCommentMail' => 'applications/differential/mail/comment', 'DifferentialCommentPreviewController' => 'applications/differential/controller/commentpreview', 'DifferentialCommentSaveController' => 'applications/differential/controller/commentsave', 'DifferentialCommitMessage' => 'applications/differential/parser/commitmessage', 'DifferentialCommitMessageData' => 'applications/differential/data/commitmessage', 'DifferentialCommitMessageParserException' => 'applications/differential/parser/commitmessage/exception', 'DifferentialController' => 'applications/differential/controller/base', 'DifferentialDAO' => 'applications/differential/storage/base', 'DifferentialDiff' => 'applications/differential/storage/diff', 'DifferentialDiffContentMail' => 'applications/differential/mail/diffcontent', 'DifferentialDiffCreateController' => 'applications/differential/controller/diffcreate', 'DifferentialDiffProperty' => 'applications/differential/storage/diffproperty', 'DifferentialDiffTableOfContentsView' => 'applications/differential/view/difftableofcontents', 'DifferentialDiffViewController' => 'applications/differential/controller/diffview', 'DifferentialHunk' => 'applications/differential/storage/hunk', 'DifferentialInlineComment' => 'applications/differential/storage/inlinecomment', 'DifferentialInlineCommentEditController' => 'applications/differential/controller/inlinecommentedit', 'DifferentialInlineCommentPreviewController' => 'applications/differential/controller/inlinecommentpreview', 'DifferentialInlineCommentView' => 'applications/differential/view/inlinecomment', 'DifferentialLintStatus' => 'applications/differential/constants/lintstatus', 'DifferentialMail' => 'applications/differential/mail/base', 'DifferentialMarkupEngineFactory' => 'applications/differential/parser/markup', 'DifferentialNewDiffMail' => 'applications/differential/mail/newdiff', 'DifferentialReviewRequestMail' => 'applications/differential/mail/reviewrequest', 'DifferentialRevision' => 'applications/differential/storage/revision', 'DifferentialRevisionCommentListView' => 'applications/differential/view/revisioncommentlist', 'DifferentialRevisionCommentView' => 'applications/differential/view/revisioncomment', 'DifferentialRevisionControlSystem' => 'applications/differential/constants/revisioncontrolsystem', 'DifferentialRevisionDetailView' => 'applications/differential/view/revisiondetail', 'DifferentialRevisionEditController' => 'applications/differential/controller/revisionedit', 'DifferentialRevisionEditor' => 'applications/differential/editor/revision', 'DifferentialRevisionListController' => 'applications/differential/controller/revisionlist', 'DifferentialRevisionListData' => 'applications/differential/data/revisionlist', 'DifferentialRevisionStatus' => 'applications/differential/constants/revisionstatus', 'DifferentialRevisionUpdateHistoryView' => 'applications/differential/view/revisionupdatehistory', 'DifferentialRevisionViewController' => 'applications/differential/controller/revisionview', 'DifferentialUnitStatus' => 'applications/differential/constants/unitstatus', 'Javelin' => 'infrastructure/javelin/api', 'LiskDAO' => 'storage/lisk/dao', 'ManiphestController' => 'applications/maniphest/controller/base', 'ManiphestDAO' => 'applications/maniphest/storage/base', 'ManiphestTask' => 'applications/maniphest/storage/task', 'ManiphestTaskCreateController' => 'applications/maniphest/controller/createtask', 'ManiphestTaskDetailController' => 'applications/maniphest/controller/taskdetail', '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', 'ManiphestTransactionSaveController' => 'applications/maniphest/controller/transactionsave', 'ManiphestTransactionType' => 'applications/maniphest/constants/transactiontype', 'Phabricator404Controller' => 'applications/base/controller/404', 'PhabricatorAuthController' => 'applications/auth/controller/base', 'PhabricatorConduitAPIController' => 'applications/conduit/controller/api', 'PhabricatorConduitConnectionLog' => 'applications/conduit/storage/connectionlog', 'PhabricatorConduitConsoleController' => 'applications/conduit/controller/console', 'PhabricatorConduitController' => 'applications/conduit/controller/base', 'PhabricatorConduitDAO' => 'applications/conduit/storage/base', 'PhabricatorConduitLogController' => 'applications/conduit/controller/log', 'PhabricatorConduitMethodCallLog' => 'applications/conduit/storage/methodcalllog', 'PhabricatorController' => 'applications/base/controller/base', 'PhabricatorDirectoryCategory' => 'applications/directory/storage/category', 'PhabricatorDirectoryCategoryDeleteController' => 'applications/directory/controller/categorydelete', 'PhabricatorDirectoryCategoryEditController' => 'applications/directory/controller/categoryedit', 'PhabricatorDirectoryCategoryListController' => 'applications/directory/controller/categorylist', 'PhabricatorDirectoryController' => 'applications/directory/controller/base', 'PhabricatorDirectoryDAO' => 'applications/directory/storage/base', 'PhabricatorDirectoryItem' => 'applications/directory/storage/item', 'PhabricatorDirectoryItemDeleteController' => 'applications/directory/controller/itemdelete', 'PhabricatorDirectoryItemEditController' => 'applications/directory/controller/itemedit', 'PhabricatorDirectoryItemListController' => 'applications/directory/controller/itemlist', 'PhabricatorDirectoryMainController' => 'applications/directory/controller/main', 'PhabricatorDraft' => 'applications/draft/storage/draft', 'PhabricatorDraftDAO' => 'applications/draft/storage/base', 'PhabricatorEmailLoginController' => 'applications/auth/controller/email', 'PhabricatorEmailTokenController' => 'applications/auth/controller/emailtoken', 'PhabricatorEnv' => 'infrastructure/env', 'PhabricatorFacebookAuthController' => 'applications/auth/controller/facebookauth', 'PhabricatorFacebookAuthDiagnosticsController' => 'applications/auth/controller/facebookauth/diagnostics', 'PhabricatorFile' => 'applications/files/storage/file', 'PhabricatorFileController' => 'applications/files/controller/base', 'PhabricatorFileDAO' => 'applications/files/storage/base', 'PhabricatorFileListController' => 'applications/files/controller/list', 'PhabricatorFileStorageBlob' => 'applications/files/storage/storageblob', 'PhabricatorFileURI' => 'applications/files/uri', 'PhabricatorFileUploadController' => 'applications/files/controller/upload', 'PhabricatorFileViewController' => 'applications/files/controller/view', 'PhabricatorLiskDAO' => 'applications/base/storage/lisk', 'PhabricatorLoginController' => 'applications/auth/controller/login', 'PhabricatorLogoutController' => 'applications/auth/controller/logout', 'PhabricatorMailImplementationAdapter' => 'applications/metamta/adapter/base', 'PhabricatorMailImplementationAmazonSESAdapter' => 'applications/metamta/adapter/amazonses', 'PhabricatorMailImplementationPHPMailerLiteAdapter' => 'applications/metamta/adapter/phpmailerlite', 'PhabricatorMetaMTAController' => 'applications/metamta/controller/base', 'PhabricatorMetaMTADAO' => 'applications/metamta/storage/base', 'PhabricatorMetaMTADaemon' => 'applications/metamta/daemon/mta', 'PhabricatorMetaMTAListController' => 'applications/metamta/controller/list', 'PhabricatorMetaMTAMail' => 'applications/metamta/storage/mail', 'PhabricatorMetaMTAMailingList' => 'applications/metamta/storage/mailinglist', 'PhabricatorMetaMTAMailingListEditController' => 'applications/metamta/controller/mailinglistedit', 'PhabricatorMetaMTAMailingListsController' => 'applications/metamta/controller/mailinglists', 'PhabricatorMetaMTASendController' => 'applications/metamta/controller/send', 'PhabricatorMetaMTAViewController' => 'applications/metamta/controller/view', 'PhabricatorObjectHandle' => 'applications/phid/handle', 'PhabricatorObjectHandleData' => 'applications/phid/handle/data', 'PhabricatorPHID' => 'applications/phid/storage/phid', 'PhabricatorPHIDAllocateController' => 'applications/phid/controller/allocate', 'PhabricatorPHIDController' => 'applications/phid/controller/base', 'PhabricatorPHIDDAO' => 'applications/phid/storage/base', 'PhabricatorPHIDListController' => 'applications/phid/controller/list', 'PhabricatorPHIDLookupController' => 'applications/phid/controller/lookup', 'PhabricatorPHIDType' => 'applications/phid/storage/type', 'PhabricatorPHIDTypeEditController' => 'applications/phid/controller/typeedit', 'PhabricatorPHIDTypeListController' => 'applications/phid/controller/typelist', 'PhabricatorPeopleController' => 'applications/people/controller/base', 'PhabricatorPeopleEditController' => 'applications/people/controller/edit', 'PhabricatorPeopleListController' => 'applications/people/controller/list', 'PhabricatorPeopleProfileController' => 'applications/people/controller/profile', 'PhabricatorRemarkupRuleDifferential' => 'infrastructure/markup/remarkup/markuprule/differential', 'PhabricatorRemarkupRuleManiphest' => 'infrastructure/markup/remarkup/markuprule/maniphest', 'PhabricatorRepository' => 'applications/repository/storage/repository', 'PhabricatorRepositoryController' => 'applications/repository/controller/base', 'PhabricatorRepositoryCreateController' => 'applications/repository/controller/create', 'PhabricatorRepositoryDAO' => 'applications/repository/storage/base', 'PhabricatorRepositoryEditController' => 'applications/repository/controller/edit', 'PhabricatorRepositoryGitHubNotification' => 'applications/repository/storage/githubnotification', 'PhabricatorRepositoryGitHubPostReceiveController' => 'applications/repository/controller/github-post-receive', 'PhabricatorRepositoryListController' => 'applications/repository/controller/list', + 'PhabricatorSearchAbstractDocument' => 'applications/search/index/abstractdocument', + 'PhabricatorSearchBaseController' => 'applications/search/controller/base', + 'PhabricatorSearchController' => 'applications/search/controller/search', + 'PhabricatorSearchDAO' => 'applications/search/storage/base', + 'PhabricatorSearchDifferentialIndexer' => 'applications/search/index/indexer/differential', + 'PhabricatorSearchDocument' => 'applications/search/storage/document/document', + 'PhabricatorSearchDocumentField' => 'applications/search/storage/document/field', + 'PhabricatorSearchDocumentIndexer' => 'applications/search/index/indexer/base', + 'PhabricatorSearchDocumentRelationship' => 'applications/search/storage/document/relationship', + 'PhabricatorSearchExecutor' => 'applications/search/execute/base', + 'PhabricatorSearchField' => 'applications/search/constants/field', + 'PhabricatorSearchManiphestIndexer' => 'applications/search/index/indexer/maniphest', + 'PhabricatorSearchMySQLExecutor' => 'applications/search/execute/mysql', + 'PhabricatorSearchQuery' => 'applications/search/storage/query', + 'PhabricatorSearchRelationship' => 'applications/search/constants/relationship', 'PhabricatorStandardPageView' => 'view/page/standard', 'PhabricatorTypeaheadCommonDatasourceController' => 'applications/typeahead/controller/common', 'PhabricatorTypeaheadDatasourceController' => 'applications/typeahead/controller/base', 'PhabricatorUser' => 'applications/people/storage/user', 'PhabricatorUserDAO' => 'applications/people/storage/base', 'PhabricatorUserSettingsController' => 'applications/people/controller/settings', 'PhabricatorXHProfController' => 'applications/xhprof/controller/base', 'PhabricatorXHProfProfileController' => 'applications/xhprof/controller/profile', 'PhabricatorXHProfProfileSymbolView' => 'applications/xhprof/view/symbol', 'PhabricatorXHProfProfileTopLevelView' => 'applications/xhprof/view/toplevel', ), 'function' => array( '_qsprintf_check_scalar_type' => 'storage/qsprintf', '_qsprintf_check_type' => 'storage/qsprintf', 'celerity_generate_unique_node_id' => 'infrastructure/celerity/api', 'celerity_register_resource_map' => 'infrastructure/celerity/map', 'javelin_render_tag' => 'infrastructure/javelin/markup', 'phabricator_format_relative_time' => 'view/utils', 'phabricator_format_timestamp' => 'view/utils', 'phabricator_format_units_generic' => 'view/utils', + 'phabricator_render_form' => 'infrastructure/javelin/markup', 'qsprintf' => 'storage/qsprintf', 'queryfx' => 'storage/queryfx', 'queryfx_all' => 'storage/queryfx', 'queryfx_one' => 'storage/queryfx', 'require_celerity_resource' => 'infrastructure/celerity/api', 'vqsprintf' => 'storage/qsprintf', 'vqueryfx' => 'storage/queryfx', 'vqueryfx_all' => 'storage/queryfx', 'xsprintf_query' => 'storage/qsprintf', ), 'requires_class' => array( 'Aphront400Response' => 'AphrontResponse', 'Aphront404Response' => 'AphrontResponse', 'AphrontAjaxResponse' => 'AphrontResponse', 'AphrontDefaultApplicationConfiguration' => 'AphrontApplicationConfiguration', 'AphrontDefaultApplicationController' => 'AphrontController', 'AphrontDialogResponse' => 'AphrontResponse', 'AphrontDialogView' => 'AphrontView', 'AphrontErrorView' => 'AphrontView', 'AphrontFileResponse' => 'AphrontResponse', 'AphrontFormCheckboxControl' => 'AphrontFormControl', 'AphrontFormControl' => 'AphrontView', 'AphrontFormDividerControl' => 'AphrontFormControl', 'AphrontFormFileControl' => 'AphrontFormControl', 'AphrontFormMarkupControl' => 'AphrontFormControl', 'AphrontFormPasswordControl' => 'AphrontFormControl', 'AphrontFormRecaptchaControl' => 'AphrontFormControl', 'AphrontFormSelectControl' => 'AphrontFormControl', 'AphrontFormStaticControl' => 'AphrontFormControl', 'AphrontFormSubmitControl' => 'AphrontFormControl', 'AphrontFormTextAreaControl' => 'AphrontFormControl', 'AphrontFormTextControl' => 'AphrontFormControl', 'AphrontFormTokenizerControl' => 'AphrontFormControl', 'AphrontFormView' => 'AphrontView', 'AphrontMySQLDatabaseConnection' => 'AphrontDatabaseConnection', 'AphrontNullView' => 'AphrontView', 'AphrontPageView' => 'AphrontView', 'AphrontPanelView' => 'AphrontView', 'AphrontQueryConnectionException' => 'AphrontQueryException', 'AphrontQueryConnectionLostException' => 'AphrontQueryRecoverableException', 'AphrontQueryCountException' => 'AphrontQueryException', 'AphrontQueryDuplicateKeyException' => 'AphrontQueryException', 'AphrontQueryObjectMissingException' => 'AphrontQueryException', 'AphrontQueryParameterException' => 'AphrontQueryException', 'AphrontQueryRecoverableException' => 'AphrontQueryException', 'AphrontRedirectException' => 'AphrontException', 'AphrontRedirectResponse' => 'AphrontResponse', 'AphrontRequestFailureView' => 'AphrontView', 'AphrontSideNavView' => 'AphrontView', 'AphrontTableView' => 'AphrontView', 'AphrontWebpageResponse' => 'AphrontResponse', 'CelerityResourceController' => 'AphrontController', 'ConduitAPI_conduit_connect_Method' => 'ConduitAPIMethod', 'ConduitAPI_differential_creatediff_Method' => 'ConduitAPIMethod', 'ConduitAPI_differential_createrevision_Method' => 'ConduitAPIMethod', 'ConduitAPI_differential_find_Method' => 'ConduitAPIMethod', 'ConduitAPI_differential_getcommitmessage_Method' => 'ConduitAPIMethod', 'ConduitAPI_differential_markcommitted_Method' => 'ConduitAPIMethod', 'ConduitAPI_differential_parsecommitmessage_Method' => 'ConduitAPIMethod', 'ConduitAPI_differential_setdiffproperty_Method' => 'ConduitAPIMethod', 'ConduitAPI_differential_updaterevision_Method' => 'ConduitAPIMethod', 'ConduitAPI_file_upload_Method' => 'ConduitAPIMethod', 'ConduitAPI_user_find_Method' => 'ConduitAPIMethod', 'DarkConsoleConfigPlugin' => 'DarkConsolePlugin', 'DarkConsoleController' => 'PhabricatorController', 'DarkConsoleErrorLogPlugin' => 'DarkConsolePlugin', 'DarkConsoleRequestPlugin' => 'DarkConsolePlugin', 'DarkConsoleServicesPlugin' => 'DarkConsolePlugin', 'DarkConsoleXHProfPlugin' => 'DarkConsolePlugin', 'DifferentialAddCommentView' => 'AphrontView', 'DifferentialCCWelcomeMail' => 'DifferentialReviewRequestMail', 'DifferentialChangeset' => 'DifferentialDAO', 'DifferentialChangesetDetailView' => 'AphrontView', 'DifferentialChangesetListView' => 'AphrontView', 'DifferentialChangesetViewController' => 'DifferentialController', 'DifferentialComment' => 'DifferentialDAO', 'DifferentialCommentMail' => 'DifferentialMail', 'DifferentialCommentPreviewController' => 'DifferentialController', 'DifferentialCommentSaveController' => 'DifferentialController', 'DifferentialController' => 'PhabricatorController', 'DifferentialDAO' => 'PhabricatorLiskDAO', 'DifferentialDiff' => 'DifferentialDAO', 'DifferentialDiffContentMail' => 'DifferentialMail', 'DifferentialDiffCreateController' => 'DifferentialController', 'DifferentialDiffProperty' => 'DifferentialDAO', 'DifferentialDiffTableOfContentsView' => 'AphrontView', 'DifferentialDiffViewController' => 'DifferentialController', 'DifferentialHunk' => 'DifferentialDAO', 'DifferentialInlineComment' => 'DifferentialDAO', 'DifferentialInlineCommentEditController' => 'DifferentialController', 'DifferentialInlineCommentPreviewController' => 'DifferentialController', 'DifferentialInlineCommentView' => 'AphrontView', 'DifferentialNewDiffMail' => 'DifferentialReviewRequestMail', 'DifferentialReviewRequestMail' => 'DifferentialMail', 'DifferentialRevision' => 'DifferentialDAO', 'DifferentialRevisionCommentListView' => 'AphrontView', 'DifferentialRevisionCommentView' => 'AphrontView', 'DifferentialRevisionDetailView' => 'AphrontView', 'DifferentialRevisionEditController' => 'DifferentialController', 'DifferentialRevisionListController' => 'DifferentialController', 'DifferentialRevisionUpdateHistoryView' => 'AphrontView', 'DifferentialRevisionViewController' => 'DifferentialController', 'ManiphestController' => 'PhabricatorController', 'ManiphestDAO' => 'PhabricatorLiskDAO', 'ManiphestTask' => 'ManiphestDAO', 'ManiphestTaskCreateController' => 'ManiphestController', 'ManiphestTaskDetailController' => 'ManiphestController', 'ManiphestTaskListController' => 'ManiphestController', 'ManiphestTaskListView' => 'AphrontView', 'ManiphestTaskSummaryView' => 'AphrontView', 'ManiphestTransaction' => 'ManiphestDAO', 'ManiphestTransactionDetailView' => 'AphrontView', 'ManiphestTransactionListView' => 'AphrontView', 'ManiphestTransactionSaveController' => 'ManiphestController', 'Phabricator404Controller' => 'PhabricatorController', 'PhabricatorAuthController' => 'PhabricatorController', 'PhabricatorConduitAPIController' => 'PhabricatorConduitController', 'PhabricatorConduitConnectionLog' => 'PhabricatorConduitDAO', 'PhabricatorConduitConsoleController' => 'PhabricatorConduitController', 'PhabricatorConduitController' => 'PhabricatorController', 'PhabricatorConduitDAO' => 'PhabricatorLiskDAO', 'PhabricatorConduitLogController' => 'PhabricatorConduitController', 'PhabricatorConduitMethodCallLog' => 'PhabricatorConduitDAO', 'PhabricatorController' => 'AphrontController', 'PhabricatorDirectoryCategory' => 'PhabricatorDirectoryDAO', 'PhabricatorDirectoryCategoryDeleteController' => 'PhabricatorDirectoryController', 'PhabricatorDirectoryCategoryEditController' => 'PhabricatorDirectoryController', 'PhabricatorDirectoryCategoryListController' => 'PhabricatorDirectoryController', 'PhabricatorDirectoryController' => 'PhabricatorController', 'PhabricatorDirectoryDAO' => 'PhabricatorLiskDAO', 'PhabricatorDirectoryItem' => 'PhabricatorDirectoryDAO', 'PhabricatorDirectoryItemDeleteController' => 'PhabricatorDirectoryController', 'PhabricatorDirectoryItemEditController' => 'PhabricatorDirectoryController', 'PhabricatorDirectoryItemListController' => 'PhabricatorDirectoryController', 'PhabricatorDirectoryMainController' => 'PhabricatorDirectoryController', 'PhabricatorDraft' => 'PhabricatorDraftDAO', 'PhabricatorDraftDAO' => 'PhabricatorLiskDAO', 'PhabricatorEmailLoginController' => 'PhabricatorAuthController', 'PhabricatorEmailTokenController' => 'PhabricatorAuthController', 'PhabricatorFacebookAuthController' => 'PhabricatorAuthController', 'PhabricatorFacebookAuthDiagnosticsController' => 'PhabricatorAuthController', 'PhabricatorFile' => 'PhabricatorFileDAO', 'PhabricatorFileController' => 'PhabricatorController', 'PhabricatorFileDAO' => 'PhabricatorLiskDAO', 'PhabricatorFileListController' => 'PhabricatorFileController', 'PhabricatorFileStorageBlob' => 'PhabricatorFileDAO', 'PhabricatorFileUploadController' => 'PhabricatorFileController', 'PhabricatorFileViewController' => 'PhabricatorFileController', 'PhabricatorLiskDAO' => 'LiskDAO', 'PhabricatorLoginController' => 'PhabricatorAuthController', 'PhabricatorLogoutController' => 'PhabricatorAuthController', 'PhabricatorMailImplementationAmazonSESAdapter' => 'PhabricatorMailImplementationPHPMailerLiteAdapter', 'PhabricatorMailImplementationPHPMailerLiteAdapter' => 'PhabricatorMailImplementationAdapter', 'PhabricatorMetaMTAController' => 'PhabricatorController', 'PhabricatorMetaMTADAO' => 'PhabricatorLiskDAO', 'PhabricatorMetaMTAListController' => 'PhabricatorMetaMTAController', 'PhabricatorMetaMTAMail' => 'PhabricatorMetaMTADAO', 'PhabricatorMetaMTAMailingList' => 'PhabricatorMetaMTADAO', 'PhabricatorMetaMTAMailingListEditController' => 'PhabricatorMetaMTAController', 'PhabricatorMetaMTAMailingListsController' => 'PhabricatorMetaMTAController', 'PhabricatorMetaMTASendController' => 'PhabricatorMetaMTAController', 'PhabricatorMetaMTAViewController' => 'PhabricatorMetaMTAController', 'PhabricatorPHID' => 'PhabricatorPHIDDAO', 'PhabricatorPHIDAllocateController' => 'PhabricatorPHIDController', 'PhabricatorPHIDController' => 'PhabricatorController', 'PhabricatorPHIDDAO' => 'PhabricatorLiskDAO', 'PhabricatorPHIDListController' => 'PhabricatorPHIDController', 'PhabricatorPHIDLookupController' => 'PhabricatorPHIDController', 'PhabricatorPHIDType' => 'PhabricatorPHIDDAO', 'PhabricatorPHIDTypeEditController' => 'PhabricatorPHIDController', 'PhabricatorPHIDTypeListController' => 'PhabricatorPHIDController', 'PhabricatorPeopleController' => 'PhabricatorController', 'PhabricatorPeopleEditController' => 'PhabricatorPeopleController', 'PhabricatorPeopleListController' => 'PhabricatorPeopleController', 'PhabricatorPeopleProfileController' => 'PhabricatorPeopleController', 'PhabricatorRemarkupRuleDifferential' => 'PhutilRemarkupRule', 'PhabricatorRemarkupRuleManiphest' => 'PhutilRemarkupRule', 'PhabricatorRepository' => 'PhabricatorRepositoryDAO', 'PhabricatorRepositoryController' => 'PhabricatorController', 'PhabricatorRepositoryCreateController' => 'PhabricatorController', 'PhabricatorRepositoryDAO' => 'PhabricatorLiskDAO', 'PhabricatorRepositoryEditController' => 'PhabricatorController', 'PhabricatorRepositoryGitHubNotification' => 'PhabricatorRepositoryDAO', 'PhabricatorRepositoryGitHubPostReceiveController' => 'PhabricatorRepositoryController', 'PhabricatorRepositoryListController' => 'PhabricatorController', + 'PhabricatorSearchBaseController' => 'PhabricatorController', + 'PhabricatorSearchController' => 'PhabricatorSearchBaseController', + 'PhabricatorSearchDAO' => 'PhabricatorLiskDAO', + 'PhabricatorSearchDifferentialIndexer' => 'PhabricatorSearchDocumentIndexer', + 'PhabricatorSearchDocument' => 'PhabricatorSearchDAO', + 'PhabricatorSearchDocumentField' => 'PhabricatorSearchDAO', + 'PhabricatorSearchDocumentRelationship' => 'PhabricatorSearchDAO', + 'PhabricatorSearchManiphestIndexer' => 'PhabricatorSearchDocumentIndexer', + 'PhabricatorSearchMySQLExecutor' => 'PhabricatorSearchExecutor', + 'PhabricatorSearchQuery' => 'PhabricatorSearchDAO', 'PhabricatorStandardPageView' => 'AphrontPageView', 'PhabricatorTypeaheadCommonDatasourceController' => 'PhabricatorTypeaheadDatasourceController', 'PhabricatorTypeaheadDatasourceController' => 'PhabricatorController', 'PhabricatorUser' => 'PhabricatorUserDAO', 'PhabricatorUserDAO' => 'PhabricatorLiskDAO', 'PhabricatorUserSettingsController' => 'PhabricatorPeopleController', '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 8db208d90e..daa9c14a8a 100644 --- a/src/aphront/default/configuration/AphrontDefaultApplicationConfiguration.php +++ b/src/aphront/default/configuration/AphrontDefaultApplicationConfiguration.php @@ -1,242 +1,247 @@ array( '$' => 'PhabricatorDirectoryMainController', ), '/directory/' => array( 'item/$' => 'PhabricatorDirectoryItemListController', 'item/edit/(?:(?P\d+)/)?$' => 'PhabricatorDirectoryItemEditController', 'item/delete/(?P\d+)/' => 'PhabricatorDirectoryItemDeleteController', 'category/$' => 'PhabricatorDirectoryCategoryListController', 'category/edit/(?:(?P\d+)/)?$' => 'PhabricatorDirectoryCategoryEditController', 'category/delete/(?P\d+)/' => 'PhabricatorDirectoryCategoryDeleteController', ), '/file/' => array( '$' => 'PhabricatorFileListController', 'upload/$' => 'PhabricatorFileUploadController', '(?Pinfo)/(?P[^/]+)/' => 'PhabricatorFileViewController', '(?Pview)/(?P[^/]+)/' => 'PhabricatorFileViewController', '(?Pdownload)/(?P[^/]+)/' => 'PhabricatorFileViewController', ), '/phid/' => array( '$' => 'PhabricatorPHIDLookupController', 'list/$' => 'PhabricatorPHIDListController', 'type/$' => 'PhabricatorPHIDTypeListController', 'type/edit/(?:(?P\d+)/)?$' => 'PhabricatorPHIDTypeEditController', 'new/$' => 'PhabricatorPHIDAllocateController', ), '/people/' => array( '$' => 'PhabricatorPeopleListController', 'edit/(?:(?P\w+)/)?$' => 'PhabricatorPeopleEditController', ), '/p/(?P\w+)/$' => 'PhabricatorPeopleProfileController', '/conduit/' => array( '$' => 'PhabricatorConduitConsoleController', 'method/(?P[^/]+)$' => 'PhabricatorConduitConsoleController', 'log/$' => 'PhabricatorConduitLogController', ), '/api/(?P[^/]+)$' => 'PhabricatorConduitAPIController', '/D(?P\d+)' => 'DifferentialRevisionViewController', '/differential/' => array( '$' => 'DifferentialRevisionListController', 'filter/(?P\w+)/$' => 'DifferentialRevisionListController', 'diff/' => array( '(?P\d+)/$' => 'DifferentialDiffViewController', 'create/$' => 'DifferentialDiffCreateController', ), 'changeset/$' => 'DifferentialChangesetViewController', 'revision/edit/(?:(?P\d+)/)?$' => 'DifferentialRevisionEditController', 'comment/' => array( 'preview/(?P\d+)/$' => 'DifferentialCommentPreviewController', 'save/$' => 'DifferentialCommentSaveController', 'inline/' => array( 'preview/(?P\d+)/$' => 'DifferentialInlineCommentPreviewController', 'edit/(?P\d+)/$' => 'DifferentialInlineCommentEditController', ), ), ), '/res/' => array( '(?Ppkg/)?(?P[a-f0-9]{8})/(?P.+\.(?:css|js))$' => 'CelerityResourceController', ), '/typeahead/' => array( 'common/(?P\w+)/$' => 'PhabricatorTypeaheadCommonDatasourceController', ), '/mail/' => array( '$' => 'PhabricatorMetaMTAListController', 'send/$' => 'PhabricatorMetaMTASendController', 'view/(?P\d+)/$' => 'PhabricatorMetaMTAViewController', 'lists/$' => 'PhabricatorMetaMTAMailingListsController', 'lists/edit/(?:(?P\d+)/)?$' => 'PhabricatorMetaMTAMailingListEditController', ), '/login/' => array( '$' => 'PhabricatorLoginController', 'email/$' => 'PhabricatorEmailLoginController', 'etoken/(?P\w+)/$' => 'PhabricatorEmailTokenController', ), '/logout/$' => 'PhabricatorLogoutController', '/facebook-auth/' => array( '$' => 'PhabricatorFacebookAuthController', 'diagnose/$' => 'PhabricatorFacebookAuthDiagnosticsController', ), '/xhprof/' => array( 'profile/(?P[^/]+)/$' => 'PhabricatorXHProfProfileController', ), '/~/' => 'DarkConsoleController', '/settings/' => array( '(?:page/(?P[^/]+)/)?$' => 'PhabricatorUserSettingsController', ), '/maniphest/' => array( '$' => 'ManiphestTaskListController', 'view/(?P\w+)/$' => 'ManiphestTaskListController', 'task/' => array( 'create/' => 'ManiphestTaskCreateController', ), 'transaction/' => array( 'save/' => 'ManiphestTransactionSaveController', ), ), '/T(?P\d+)$' => 'ManiphestTaskDetailController', '/github-post-receive/(?P\d+)/(?P[^/]+)/$' => 'PhabricatorRepositoryGitHubPostReceiveController', '/repository/' => array( '$' => 'PhabricatorRepositoryListController', 'create/$' => 'PhabricatorRepositoryCreateController', 'edit/(?P\d+)/$' => 'PhabricatorRepositoryEditController', 'delete/(?P\d+)/$' => 'PhabricatorRepositoryDeleteController', ), + + '/search/' => array( + '$' => 'PhabricatorSearchController', + '(?P\d+)/$' => 'PhabricatorSearchController', + ), ); } public function buildRequest() { $request = new AphrontRequest($this->getHost(), $this->getPath()); $request->setRequestData($_GET + $_POST); $request->setApplicationConfiguration($this); return $request; } public function handleException(Exception $ex) { $class = phutil_escape_html(get_class($ex)); $message = phutil_escape_html($ex->getMessage()); $content = '
'. '

Unhandled Exception "'.$class.'": '.$message.'

'. ''.phutil_escape_html((string)$ex).''. '
'; $view = new PhabricatorStandardPageView(); $view->setRequest($this->getRequest()); $view->appendChild($content); $response = new AphrontWebpageResponse(); $response->setContent($view->render()); return $response; } public function willSendResponse(AphrontResponse $response) { $request = $this->getRequest(); if ($response instanceof AphrontDialogResponse) { if (!$request->isAjax()) { $view = new PhabricatorStandardPageView(); $view->setRequest($request); $view->appendChild( '
'. $response->buildResponseString(). '
'); $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( '

The page you requested was not found.

'); $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()); } } diff --git a/src/applications/differential/editor/revision/DifferentialRevisionEditor.php b/src/applications/differential/editor/revision/DifferentialRevisionEditor.php index 99badd804d..027716c392 100644 --- a/src/applications/differential/editor/revision/DifferentialRevisionEditor.php +++ b/src/applications/differential/editor/revision/DifferentialRevisionEditor.php @@ -1,603 +1,605 @@ revision = $revision; $this->actorPHID = $actor_phid; } public static function newRevisionFromConduitWithDiff( array $fields, DifferentialDiff $diff, $user_phid) { $revision = new DifferentialRevision(); $revision->setPHID($revision->generatePHID()); $revision->setAuthorPHID($user_phid); $revision->setStatus(DifferentialRevisionStatus::NEEDS_REVIEW); $editor = new DifferentialRevisionEditor($revision, $user_phid); $editor->copyFieldsFromConduit($fields); $editor->addDiff($diff, null); $editor->save(); return $revision; } public function copyFieldsFromConduit(array $fields) { $revision = $this->revision; $revision->setTitle((string)$fields['title']); $revision->setSummary((string)$fields['summary']); $revision->setTestPlan((string)$fields['testPlan']); $revision->setBlameRevision((string)$fields['blameRevision']); $revision->setRevertPlan((string)$fields['revertPlan']); $this->setReviewers($fields['reviewerPHIDs']); $this->setCCPHIDs($fields['ccPHIDs']); } /* public static function newRevisionFromRawMessageWithDiff( DifferentialRawMessage $message, Diff $diff, $user) { if ($message->getRevisionID()) { throw new Exception( "The provided commit message is already associated with a ". "Differential revision."); } if ($message->getReviewedByNames()) { throw new Exception( "The provided commit message contains a 'Reviewed By:' field."); } $revision = new DifferentialRevision(); $revision->setPHID($revision->generatePHID()); $revision->setOwnerID($user); $revision->setStatus(DifferentialRevisionStatus::NEEDS_REVIEW); $revision->attachReviewers(array()); $revision->attachCCPHIDs(array()); $editor = new DifferentialRevisionEditor($revision, $user); self::copyFields($editor, $revision, $message, $user); $editor->addDiff($diff, null); $editor->save(); return $revision; } public static function copyFields( DifferentialRevisionEditor $editor, DifferentialRevision $revision, DifferentialRawMessage $message, $user) { $revision->setName($message->getTitle()); $revision->setSummary($message->getSummary()); $revision->setTestPlan($message->getTestPlan()); $revision->setSVNBlameRevision($message->getBlameRevision()); $revision->setRevert($message->getRevertPlan()); $revision->setPlatformImpact($message->getPlatformImpact()); $revision->setBugzillaID($message->getBugzillaID()); $editor->setReviewers($message->getReviewerPHIDs()); $editor->setCCPHIDs($message->getCCPHIDs()); } */ public function getRevision() { return $this->revision; } public function setReviewers(array $reviewers) { $this->reviewers = $reviewers; return $this; } public function setCCPHIDs(array $cc) { $this->cc = $cc; return $this; } public function addDiff(DifferentialDiff $diff, $comments) { if ($diff->getRevisionID() && $diff->getRevisionID() != $this->getRevision()->getID()) { $diff_id = (int)$diff->getID(); $targ_id = (int)$this->getRevision()->getID(); $real_id = (int)$diff->getRevisionID(); throw new Exception( "Can not attach diff #{$diff_id} to Revision D{$targ_id}, it is ". "already attached to D{$real_id}."); } $this->diff = $diff; $this->comments = $comments; return $this; } protected function getDiff() { return $this->diff; } protected function getComments() { return $this->comments; } protected function getActorPHID() { return $this->actorPHID; } public function isNewRevision() { return !$this->getRevision()->getID(); } /** * A silent update does not trigger Herald rules or send emails. This is used * for auto-amends at commit time. */ public function setSilentUpdate($silent) { $this->silentUpdate = $silent; return $this; } public function save() { $revision = $this->getRevision(); // TODO // $revision->openTransaction(); $is_new = $this->isNewRevision(); if ($is_new) { // These fields aren't nullable; set them to sensible defaults if they // haven't been configured. We're just doing this so we can generate an // ID for the revision if we don't have one already. $revision->setLineCount(0); if ($revision->getStatus() === null) { $revision->setStatus(DifferentialRevisionStatus::NEEDS_REVIEW); } if ($revision->getTitle() === null) { $revision->setTitle('Untitled Revision'); } if ($revision->getAuthorPHID() === null) { $revision->setAuthorPHID($this->getActorPHID()); } $revision->save(); } $revision->loadRelationships(); if ($this->reviewers === null) { $this->reviewers = $revision->getReviewers(); } if ($this->cc === null) { $this->cc = $revision->getCCPHIDs(); } // We're going to build up three dictionaries: $add, $rem, and $stable. The // $add dictionary has added reviewers/CCs. The $rem dictionary has // reviewers/CCs who have been removed, and the $stable array is // reviewers/CCs who haven't changed. We're going to send new reviewers/CCs // a different ("welcome") email than we send stable reviewers/CCs. $old = array( 'rev' => array_fill_keys($revision->getReviewers(), true), 'ccs' => array_fill_keys($revision->getCCPHIDs(), true), ); $diff = $this->getDiff(); $xscript_header = null; $xscript_uri = null; $new = array( 'rev' => array_fill_keys($this->reviewers, true), 'ccs' => array_fill_keys($this->cc, true), ); $rem_ccs = array(); if ($diff) { $diff->setRevisionID($revision->getID()); $revision->setLineCount($diff->getLineCount()); // TODO! // $revision->setRepositoryID($diff->getRepositoryID()); /* $iface = new DifferentialRevisionHeraldable($revision); $iface->setExplicitCCs($new['ccs']); $iface->setExplicitReviewers($new['rev']); $iface->setForbiddenCCs($revision->getForbiddenCCPHIDs()); $iface->setForbiddenReviewers($revision->getForbiddenReviewers()); $iface->setDiff($diff); $xscript = HeraldEngine::loadAndApplyRules($iface); $xscript_uri = $xscript->getURI(); $xscript_phid = $xscript->getPHID(); $xscript_header = $xscript->getXHeraldRulesHeader(); $sub = array( 'rev' => array(), 'ccs' => $iface->getCCsAddedByHerald(), ); $rem_ccs = $iface->getCCsRemovedByHerald(); */ // TODO! $sub = array( 'rev' => array(), 'ccs' => array(), ); } else { $sub = array( 'rev' => array(), 'ccs' => array(), ); } // Remove any CCs which are prevented by Herald rules. $sub['ccs'] = array_diff_key($sub['ccs'], $rem_ccs); $new['ccs'] = array_diff_key($new['ccs'], $rem_ccs); $add = array(); $rem = array(); $stable = array(); foreach (array('rev', 'ccs') as $key) { $add[$key] = array(); if ($new[$key] !== null) { $add[$key] += array_diff_key($new[$key], $old[$key]); } $add[$key] += array_diff_key($sub[$key], $old[$key]); $combined = $sub[$key]; if ($new[$key] !== null) { $combined += $new[$key]; } $rem[$key] = array_diff_key($old[$key], $combined); $stable[$key] = array_diff_key($old[$key], $add[$key] + $rem[$key]); } self::alterReviewers( $revision, $this->reviewers, array_keys($rem['rev']), array_keys($add['rev']), $this->actorPHID); /* // TODO: When Herald is brought over, run through this stuff to figure // out which adds are Herald's fault. if ($add['ccs'] || $rem['ccs']) { foreach (array_keys($add['ccs']) as $id) { if (empty($new['ccs'][$id])) { $reason_phid = 'TODO';//$xscript_phid; } else { $reason_phid = $this->getActorPHID(); } } foreach (array_keys($rem['ccs']) as $id) { if (empty($new['ccs'][$id])) { $reason_phid = $this->getActorPHID(); } else { $reason_phid = 'TODO';//$xscript_phid; } } } */ self::alterCCs( $revision, $this->cc, array_keys($rem['ccs']), array_keys($add['ccs']), $this->actorPHID); // Add the author to the relevant set of users so they get a copy of the // email. if (!$this->silentUpdate) { if ($is_new) { $add['rev'][$this->getActorPHID()] = true; } else { $stable['rev'][$this->getActorPHID()] = true; } } $mail = array(); $phids = array($this->getActorPHID()); $handles = id(new PhabricatorObjectHandleData($phids)) ->loadHandles(); $actor_handle = $handles[$this->getActorPHID()]; $changesets = null; $comment = null; if ($diff) { $changesets = $diff->loadChangesets(); // TODO: This should probably be in DifferentialFeedbackEditor? if (!$is_new) { $comment = $this->createComment(); } if ($comment) { $mail[] = id(new DifferentialNewDiffMail( $revision, $actor_handle, $changesets)) ->setIsFirstMailAboutRevision($is_new) ->setIsFirstMailToRecipients($is_new) ->setComments($this->getComments()) ->setToPHIDs(array_keys($stable['rev'])) ->setCCPHIDs(array_keys($stable['ccs'])); } // Save the changes we made above. $diff->setDescription(substr($this->getComments(), 0, 80)); $diff->save(); // An updated diff should require review, as long as it's not committed // or accepted. The "accepted" status is "sticky" to encourage courtesy // re-diffs after someone accepts with minor changes/suggestions. $status = $revision->getStatus(); if ($status != DifferentialRevisionStatus::COMMITTED && $status != DifferentialRevisionStatus::ACCEPTED) { $revision->setStatus(DifferentialRevisionStatus::NEEDS_REVIEW); } } else { $diff = $revision->loadActiveDiff(); if ($diff) { $changesets = $diff->loadChangesets(); } else { $changesets = array(); } } $revision->save(); // TODO // $revision->saveTransaction(); $event = array( 'revision_id' => $revision->getID(), 'PHID' => $revision->getPHID(), 'action' => $is_new ? 'create' : 'update', 'actor' => $this->getActorPHID(), ); +// TODO: When timelines get implemented, move indexing to them. + PhabricatorSearchDifferentialIndexer::indexRevision($revision); // TODO // id(new ToolsTimelineEvent('difx', fb_json_encode($event)))->record(); if ($this->silentUpdate) { return; } $revision->loadRelationships(); if ($add['rev']) { $message = id(new DifferentialNewDiffMail( $revision, $actor_handle, $changesets)) ->setIsFirstMailAboutRevision($is_new) ->setIsFirstMailToRecipients(true) ->setToPHIDs(array_keys($add['rev'])); if ($is_new) { // The first time we send an email about a revision, put the CCs in // the "CC:" field of the same "Review Requested" email that reviewers // get, so you don't get two initial emails if you're on a list that // is CC'd. $message->setCCPHIDs(array_keys($add['ccs'])); } $mail[] = $message; } // If you were added as a reviewer and a CC, just give you the reviewer // email. We could go to greater lengths to prevent this, but there's // bunch of stuff with list subscriptions anyway. You can still get two // emails, but only if a revision is updated and you are added as a reviewer // at the same time a list you are on is added as a CC, which is rare and // reasonable. $add['ccs'] = array_diff_key($add['ccs'], $add['rev']); if (!$is_new && $add['ccs']) { $mail[] = id(new DifferentialCCWelcomeMail( $revision, $actor_handle, $changesets)) ->setIsFirstMailToRecipients(true) ->setToPHIDs(array_keys($add['ccs'])); } foreach ($mail as $message) { // TODO // $message->setHeraldTranscriptURI($xscript_uri); // $message->setXHeraldRulesHeader($xscript_header); $message->send(); } } protected static function alterCCs( DifferentialRevision $revision, array $stable_phids, array $rem_phids, array $add_phids, $reason_phid) { return self::alterRelationships( $revision, $stable_phids, $rem_phids, $add_phids, $reason_phid, DifferentialRevision::RELATION_SUBSCRIBED); } public static function alterReviewers( DifferentialRevision $revision, array $stable_phids, array $rem_phids, array $add_phids, $reason_phid) { return self::alterRelationships( $revision, $stable_phids, $rem_phids, $add_phids, $reason_phid, DifferentialRevision::RELATION_REVIEWER); } private static function alterRelationships( DifferentialRevision $revision, array $stable_phids, array $rem_phids, array $add_phids, $reason_phid, $relation_type) { $rem_map = array_fill_keys($rem_phids, true); $add_map = array_fill_keys($add_phids, true); $seq_map = array_values($stable_phids); $seq_map = array_flip($seq_map); foreach ($rem_map as $phid => $ignored) { if (!isset($seq_map[$phid])) { $seq_map[$phid] = count($seq_map); } } foreach ($add_map as $phid => $ignored) { if (!isset($seq_map[$phid])) { $seq_map[$phid] = count($seq_map); } } $raw = $revision->getRawRelations($relation_type); $raw = ipull($raw, null, 'objectPHID'); $sequence = count($seq_map); foreach ($raw as $phid => $ignored) { if (isset($seq_map[$phid])) { $raw[$phid]['sequence'] = $seq_map[$phid]; } else { $raw[$phid]['sequence'] = $sequence++; } } $raw = isort($raw, 'sequence'); foreach ($raw as $phid => $ignored) { if (isset($rem_map[$phid])) { unset($raw[$phid]); } } foreach ($add_phids as $add) { $raw[$add] = array( 'objectPHID' => $add, 'sequence' => idx($seq_map, $add, $sequence++), 'reasonPHID' => $reason_phid, ); } $conn_w = $revision->establishConnection('w'); $sql = array(); foreach ($raw as $relation) { $sql[] = qsprintf( $conn_w, '(%d, %s, %s, %d, %s)', $revision->getID(), $relation_type, $relation['objectPHID'], $relation['sequence'], $relation['reasonPHID']); } $conn_w->openTransaction(); queryfx( $conn_w, 'DELETE FROM %T WHERE revisionID = %d AND relation = %s', DifferentialRevision::RELATIONSHIP_TABLE, $revision->getID(), $relation_type); if ($sql) { queryfx( $conn_w, 'INSERT INTO %T (revisionID, relation, objectPHID, sequence, reasonPHID) VALUES %Q', DifferentialRevision::RELATIONSHIP_TABLE, implode(', ', $sql)); } $conn_w->saveTransaction(); } private function createComment() { $revision_id = $this->revision->getID(); $comment = id(new DifferentialComment()) ->setAuthorPHID($this->getActorPHID()) ->setRevisionID($revision_id) ->setContent($this->getComments()) ->setAction('update'); $comment->save(); return $comment; } } diff --git a/src/applications/differential/editor/revision/__init__.php b/src/applications/differential/editor/revision/__init__.php index bc0bf4fae8..314d676c81 100644 --- a/src/applications/differential/editor/revision/__init__.php +++ b/src/applications/differential/editor/revision/__init__.php @@ -1,21 +1,22 @@ getCCPHIDs(); $email_to = array(); $email_to[] = $task->getOwnerPHID(); foreach ($transactions as $key => $transaction) { $type = $transaction->getTransactionType(); $new = $transaction->getNewValue(); $email_to[] = $transaction->getAuthorPHID(); switch ($type) { case ManiphestTransactionType::TYPE_NONE: $old = null; break; case ManiphestTransactionType::TYPE_STATUS: $old = $task->getStatus(); break; case ManiphestTransactionType::TYPE_OWNER: $old = $task->getOwnerPHID(); break; case ManiphestTransactionType::TYPE_CCS: $old = $task->getCCPHIDs(); break; case ManiphestTransactionType::TYPE_PRIORITY: $old = $task->getPriority(); break; default: throw new Exception('Unknown action type.'); } if (($old !== null) && ($old == $new)) { if (count($transactions) > 1 && !$transaction->hasComments()) { // If we have at least one other transaction and this one isn't // doing anything and doesn't have any comments, just throw it // away. unset($transactions[$key]); continue; } else { $transaction->setOldValue(null); $transaction->setNewValue(null); $transaction->setTransactionType(ManiphestTransactionType::TYPE_NONE); } } else { switch ($type) { case ManiphestTransactionType::TYPE_NONE: break; case ManiphestTransactionType::TYPE_STATUS: $task->setStatus($new); break; case ManiphestTransactionType::TYPE_OWNER: $task->setOwnerPHID($new); break; case ManiphestTransactionType::TYPE_CCS: $task->setCCPHIDs($new); break; case ManiphestTransactionType::TYPE_PRIORITY: $task->setPriority($new); break; default: throw new Exception('Unknown action type.'); } $transaction->setOldValue($old); $transaction->setNewValue($new); } } $task->save(); foreach ($transactions as $transaction) { $transaction->setTaskID($task->getID()); $transaction->save(); } $email_to[] = $task->getOwnerPHID(); $email_cc = array_merge( $email_cc, $task->getCCPHIDs()); + // TODO: Do this offline via timeline + PhabricatorSearchManiphestIndexer::indexTask($task); + $this->sendEmail($task, $transactions, $email_to, $email_cc); } private function sendEmail($task, $transactions, $email_to, $email_cc) { $email_to = array_filter(array_unique($email_to)); $email_cc = array_filter(array_unique($email_cc)); $phids = array(); foreach ($transactions as $transaction) { foreach ($transaction->extractPHIDs() as $phid) { $phids[$phid] = true; } } $phids = array_keys($phids); $handles = id(new PhabricatorObjectHandleData($phids)) ->loadHandles(); $view = new ManiphestTransactionDetailView(); $view->setTransactionGroup($transactions); $view->setHandles($handles); list($action, $body) = $view->renderForEmail($with_date = false); $is_create = false; foreach ($transactions as $transaction) { $type = $transaction->getTransactionType(); if (($type == ManiphestTransactionType::TYPE_STATUS) && ($transaction->getOldValue() === null) && ($transaction->getNewValue() == ManiphestTaskStatus::STATUS_OPEN)) { $is_create = true; } } $task_uri = PhabricatorEnv::getURI('/T'.$task->getID()); if ($is_create) { $body .= "\n\n". "TASK DESCRIPTION\n". " ".$task->getDescription(); } $body .= "\n\n". "TASK DETAIL\n". " ".$task_uri."\n"; $base = substr(md5($task->getPHID()), 0, 27).' '.pack("N", time()); $thread_index = base64_encode($base); $message_id = 'getPHID().'>'; id(new PhabricatorMetaMTAMail()) ->setSubject( '[Maniphest] T'.$task->getID().' '.$action.': '.$task->getTitle()) ->setFrom($transaction->getAuthorPHID()) ->addTos($email_to) ->addCCs($email_cc) ->addHeader('Thread-Index', $thread_index) ->addHeader('Thread-Topic', 'Maniphest Task '.$task->getID()) ->addHeader('In-Reply-To', $message_id) ->addHeader('References', $message_id) ->setRelatedPHID($task->getPHID()) ->setBody($body) ->save(); } } diff --git a/src/applications/maniphest/editor/transaction/__init__.php b/src/applications/maniphest/editor/transaction/__init__.php index d55c40092f..75f2b7d20e 100644 --- a/src/applications/maniphest/editor/transaction/__init__.php +++ b/src/applications/maniphest/editor/transaction/__init__.php @@ -1,19 +1,20 @@ phids = $phids; } public function loadHandles() { $types = array(); foreach ($this->phids as $phid) { $type = $this->lookupType($phid); $types[$type][] = $phid; } $handles = array(); foreach ($types as $type => $phids) { switch ($type) { case 'USER': $class = 'PhabricatorUser'; PhutilSymbolLoader::loadClass($class); $object = newv($class, array()); $users = $object->loadAllWhere('phid IN (%Ls)', $phids); $users = mpull($users, null, 'getPHID'); foreach ($phids as $phid) { $handle = new PhabricatorObjectHandle(); $handle->setPHID($phid); if (empty($users[$phid])) { $handle->setType(self::TYPE_UNKNOWN); $handle->setName('Unknown User'); } else { $user = $users[$phid]; $handle->setType($type); $handle->setName($user->getUsername()); $handle->setURI('/p/'.$user->getUsername().'/'); $handle->setEmail($user->getEmail()); $handle->setFullName( $user->getUsername().' ('.$user->getRealName().')'); $img_phid = $user->getProfileImagePHID(); if ($img_phid) { $handle->setImageURI( PhabricatorFileURI::getViewURIForPHID($img_phid)); } } $handles[$phid] = $handle; } break; case 'MLST': $class = 'PhabricatorMetaMTAMailingList'; PhutilSymbolLoader::loadClass($class); $object = newv($class, array()); $lists = $object->loadAllWhere('phid IN (%Ls)', $phids); $lists = mpull($lists, null, 'getPHID'); foreach ($phids as $phid) { $handle = new PhabricatorObjectHandle(); $handle->setPHID($phid); if (empty($lists[$phid])) { $handle->setType(self::TYPE_UNKNOWN); $handle->setName('Unknown Mailing List'); } else { $list = $lists[$phid]; $handle->setType($type); $handle->setEmail($list->getEmail()); $handle->setName($list->getName()); $handle->setURI($list->getURI()); $handle->setFullName($list->getName()); } $handles[$phid] = $handle; } break; + case 'DREV': + $class = 'DifferentialRevision'; + PhutilSymbolLoader::loadClass($class); + $object = newv($class, array()); + + $revs = $object->loadAllWhere('phid in (%Ls)', $phids); + $revs = mpull($revs, null, 'getPHID'); + + foreach ($phids as $phid) { + $handle = new PhabricatorObjectHandle(); + $handle->setPHID($phid); + if (empty($revs[$phid])) { + $handle->setType(self::TYPE_UNKNOWN); + $handle->setName('Unknown Revision'); + } else { + $rev = $revs[$phid]; + $handle->setType($type); + $handle->setName($rev->getTitle()); + $handle->setURI('/D'.$rev->getID()); + } + $handles[$phid] = $handle; + } + break; + case 'TASK': + $class = 'ManiphestTask'; + PhutilSymbolLoader::loadClass($class); + $object = newv($class, array()); + + $tasks = $object->loadAllWhere('phid in (%Ls)', $phids); + $tasks = mpull($tasks, null, 'getPHID'); + + foreach ($phids as $phid) { + $handle = new PhabricatorObjectHandle(); + $handle->setPHID($phid); + if (empty($tasks[$phid])) { + $handle->setType(self::TYPE_UNKNOWN); + $handle->setName('Unknown Revision'); + } else { + $task = $tasks[$phid]; + $handle->setType($type); + $handle->setName($task->getTitle()); + $handle->setURI('/T'.$task->getID()); + } + $handles[$phid] = $handle; + } + break; case 'FILE': $class = 'PhabricatorFile'; PhutilSymbolLoader::loadClass($class); $object = newv($class, array()); $files = $object->loadAllWhere('phid IN (%Ls)', $phids); $files = mpull($files, null, 'getPHID'); foreach ($phids as $phid) { $handle = new PhabricatorObjectHandle(); $handle->setPHID($phid); if (empty($files[$phid])) { $handle->setType(self::TYPE_UNKNOWN); $handle->setName('Unknown File'); } else { $file = $files[$phid]; $handle->setType($type); $handle->setName($file->getName()); $handle->setURI($file->getViewURI()); } $handles[$phid] = $handle; } break; default: foreach ($phids as $phid) { $handle = new PhabricatorObjectHandle(); $handle->setType($type); $handle->setPHID($phid); $handle->setName('Unknown Object'); $handles[$phid] = $handle; } break; } } return $handles; } private function lookupType($phid) { $matches = null; if (preg_match('/^PHID-([^-]{4})-/', $phid, $matches)) { return $matches[1]; } return self::TYPE_UNKNOWN; } } diff --git a/scripts/__init_script__.php b/src/applications/search/constants/field/PhabricatorSearchField.php similarity index 52% copy from scripts/__init_script__.php copy to src/applications/search/constants/field/PhabricatorSearchField.php index bdf6abeb83..25609d9247 100644 --- a/scripts/__init_script__.php +++ b/src/applications/search/constants/field/PhabricatorSearchField.php @@ -1,34 +1,25 @@ buildStandardPageView(); -phutil_load_library(dirname(__FILE__).'/../src/'); + $page->setApplicationName('Search'); + $page->setBaseURI('/search/'); + $page->setTitle(idx($data, 'title')); + $page->setGlyph("(?)"); + $page->appendChild($view); -require_once dirname(dirname(__FILE__)).'/conf/__init_conf__.php'; + $response = new AphrontWebpageResponse(); + return $response->setContent($page->render()); + } + +} diff --git a/src/applications/search/controller/base/__init__.php b/src/applications/search/controller/base/__init__.php new file mode 100644 index 0000000000..55de27de55 --- /dev/null +++ b/src/applications/search/controller/base/__init__.php @@ -0,0 +1,15 @@ +id = idx($data, 'id'); + } + + public function processRequest() { + $request = $this->getRequest(); + $user = $request->getUser(); + + if ($this->id) { + $query = id(new PhabricatorSearchQuery())->load($this->id); + if (!$query) { + return new Aphront404Response(); + } + } else { + $query = new PhabricatorSearchQuery(); + + if ($request->isFormPost()) { + $query->setQuery($request->getStr('query')); + $query->save(); + return id(new AphrontRedirectResponse()) + ->setURI('/search/'.$query->getID().'/'); + } + } + + + $search_form = new AphrontFormView(); + $search_form + ->setUser($user) + ->setAction('/search/') + ->appendChild( + id(new AphrontFormTextControl()) + ->setLabel('Search') + ->setName('query') + ->setValue($query->getQuery())) + ->appendChild( + id(new AphrontFormSubmitControl()) + ->setValue('Search')); + + $search_panel = new AphrontPanelView(); + $search_panel->setHeader('Search Phabricator'); + $search_panel->appendChild($search_form); + + if ($query->getID()) { + $executor = new PhabricatorSearchMySQLExecutor(); + $results = $executor->executeSearch($query); + $results = ipull($results, 'phid'); + $handles = id(new PhabricatorObjectHandleData($results)) + ->loadHandles(); + $results = array(); + foreach ($handles as $handle) { + $results[] = '

'.$handle->renderLink().'

'; + } + $results = + '
'. + implode("\n", $results). + '
'; + } else { + $results = null; + } + + $results = print_r($results, true); + + return $this->buildStandardPageResponse( + array( + $search_panel, + $results, + ), + array( + 'title' => 'Results: what', + )); + } + +} diff --git a/src/applications/search/controller/search/__init__.php b/src/applications/search/controller/search/__init__.php new file mode 100644 index 0000000000..a116849ddf --- /dev/null +++ b/src/applications/search/controller/search/__init__.php @@ -0,0 +1,22 @@ +getTableName(); + $t_field = $dao_field->getTableName(); + + $conn_r = $dao_doc->establishConnection('r'); + + $q = $query->getQuery(); + + if (strlen($q)) { + $join[] = qsprintf( + $conn_r, + "{$t_field} field ON field.phid = document.phid"); + $where[] = qsprintf( + $conn_r, + 'MATCH(corpus) AGAINST (%s)', + $q); +/* + if ($query->getParameter('order') == AdjutantQuery::ORDER_RELEVANCE) { + $order = qsprintf( + $conn_r, + 'ORDER BY MATCH(corpus) AGAINST (%s) DESC', + $q); + } +*/ + $field = $query->getParameter('field'); + if ($field/* && $field != AdjutantQuery::FIELD_ALL*/) { + $where[] = qsprintf( + $conn_r, + 'field.field = %s', + $field); + } + } + + if ($query->getParameter('type')) { + $where[] = qsprintf( + $conn_r, + 'document.documentType = %s', + $query->getParameter('type')); + } + +/* + $join[] = $this->joinRelationship( + $conn_r, + $query, + 'author', + AdjutantRelationship::RELATIONSHIP_AUTHOR); + $join[] = $this->joinRelationship( + $conn_r, + $query, + 'reviewer', + AdjutantRelationship::RELATIONSHIP_REVIEWER); + $join[] = $this->joinRelationship( + $conn_r, + $query, + 'subscriber', + AdjutantRelationship::RELATIONSHIP_SUBSCRIBER); + $join[] = $this->joinRelationship( + $conn_r, + $query, + 'repository', + AdjutantRelationship::RELATIONSHIP_REPOSITORY); +*/ + $join = array_filter($join); + + foreach ($join as $key => $clause) { + $join[$key] = ' JOIN '.$clause; + } + $join = implode(' ', $join); + + if ($where) { + $where = 'WHERE '.implode(' AND ', $where); + } else { + $where = ''; + } + + $hits = queryfx_all( + $conn_r, + 'SELECT DISTINCT + document.phid, + document.documentType, + document.documentCreated FROM %T document %Q %Q %Q + LIMIT 50', + $t_doc, + $join, + $where, + $order); + + return $hits; + } + + protected function joinRelationship($conn, $query, $field, $type) { + $fbids = $query->getParameter($field, array()); + if (!$fbids) { + return null; + } + return qsprintf( + $conn, + 'relationship AS %C ON %C.fbid = data.fbid AND %C.relation = %s + AND %C.relatedFBID in (%Ld)', + $field, + $field, + $field, + $type, + $field, + $fbids); + } + + +} diff --git a/src/applications/search/execute/mysql/__init__.php b/src/applications/search/execute/mysql/__init__.php new file mode 100644 index 0000000000..a356035a92 --- /dev/null +++ b/src/applications/search/execute/mysql/__init__.php @@ -0,0 +1,16 @@ +phid = $phid; + return $this; + } + + public function setDocumentType($document_type) { + $this->documentType = $document_type; + return $this; + } + + public function setDocumentTitle($title) { + $this->documentTitle = $title; + $this->addField(PhabricatorSearchField::FIELD_TITLE, $title); + return $this; + } + + public function addField($field, $corpus, $aux_phid = null) { + $this->fields[] = array($field, $corpus, $aux_phid); + return $this; + } + + public function addRelationship($type, $related_phid) { + $this->relationships[] = array($type, $related_phid); + return $this; + } + + public function setDocumentCreated($date) { + $this->documentCreated = $date; + return $this; + } + + public function setDocumentModified($date) { + $this->documentModified = $date; + return $this; + } + + public function getPHID() { + return $this->phid; + } + + public function getDocumentType() { + return $this->documentType; + } + + public function getDocumentTitle() { + return $this->documentTitle; + } + + public function getDocumentCreated() { + return $this->documentCreated; + } + + public function getDocumentModified() { + return $this->documentModified; + } + + public function getFieldData() { + return $this->fields; + } + + public function getRelationshipData() { + return $this->relationships; + } +} diff --git a/src/applications/search/index/abstractdocument/__init__.php b/src/applications/search/index/abstractdocument/__init__.php new file mode 100644 index 0000000000..355519d478 --- /dev/null +++ b/src/applications/search/index/abstractdocument/__init__.php @@ -0,0 +1,12 @@ +setPHID($rev->getPHID()); + $doc->setDocumentType('DREV'); + $doc->setDocumentTitle($rev->getTitle()); + $doc->setDocumentCreated($rev->getDateCreated()); + $doc->setDocumentModified($rev->getDateModified()); + + $doc->addField( + PhabricatorSearchField::FIELD_BODY, + $rev->getSummary()); + $doc->addField( + PhabricatorSearchField::FIELD_TEST_PLAN, + $rev->getTestPlan()); + + $doc->addRelationship( + PhabricatorSearchRelationship::RELATIONSHIP_AUTHOR, + $rev->getAuthorPHID()); + + PhabricatorSearchDocument::reindexAbstractDocument($doc); + } +} diff --git a/src/applications/search/index/indexer/differential/__init__.php b/src/applications/search/index/indexer/differential/__init__.php new file mode 100644 index 0000000000..ba69035939 --- /dev/null +++ b/src/applications/search/index/indexer/differential/__init__.php @@ -0,0 +1,16 @@ +setPHID($task->getPHID()); + $doc->setDocumentType('TASK'); + $doc->setDocumentTitle($task->getTitle()); + $doc->setDocumentCreated($task->getDateCreated()); + $doc->setDocumentModified($task->getDateModified()); + + $doc->addField( + PhabricatorSearchField::FIELD_BODY, + $task->getDescription()); + + $doc->addRelationship( + PhabricatorSearchRelationship::RELATIONSHIP_AUTHOR, + $task->getAuthorPHID()); + + PhabricatorSearchDocument::reindexAbstractDocument($doc); + } +} diff --git a/src/applications/search/index/indexer/maniphest/__init__.php b/src/applications/search/index/indexer/maniphest/__init__.php new file mode 100644 index 0000000000..6bc0288b98 --- /dev/null +++ b/src/applications/search/index/indexer/maniphest/__init__.php @@ -0,0 +1,16 @@ + false, + self::CONFIG_IDS => self::IDS_MANUAL, + ) + parent::getConfiguration(); + } + + public function getIDKey() { + return 'phid'; + } + + public static function reindexAbstractDocument( + PhabricatorSearchAbstractDocument $doc) { + + $phid = $doc->getPHID(); + if (!$phid) { + throw new Exception("Document has no PHID!"); + } + + $store = new PhabricatorSearchDocument(); + $store->setPHID($doc->getPHID()); + $store->setDocumentType($doc->getDocumentType()); + $store->setDocumentTitle($doc->getDocumentTitle()); + $store->setDocumentCreated($doc->getDocumentCreated()); + $store->setDocumentModified($doc->getDocumentModified()); + $store->replace(); + + $conn_w = $store->establishConnection('w'); + + $field_dao = new PhabricatorSearchDocumentField(); + queryfx( + $conn_w, + 'DELETE FROM %T WHERE phid = %s', + $field_dao->getTableName(), + $phid); + foreach ($doc->getFieldData() as $field) { + list($ftype, $corpus, $aux_phid) = $field; + queryfx( + $conn_w, + 'INSERT INTO %T (phid, field, auxPHId, corpus) '. + ' VALUES (%s, %s, %ns, %s)', + $field_dao->getTableName(), + $phid, + $ftype, + $aux_phid, + $corpus); + } + + + $sql = array(); + foreach ($doc->getRelationshipData() as $relationship) { + list($rtype, $toPHID) = $relationship; + $sql[] = qsprintf( + $conn_w, + '(%s, %s, %s)', + $phid, + $toPHID, + $rtype); + } + + $rship_dao = new PhabricatorSearchDocumentRelationship(); + queryfx( + $conn_w, + 'DELETE FROM %T WHERE phid = %s', + $rship_dao->getTableName(), + $phid); + if ($sql) { + queryfx( + $conn_w, + 'INSERT INTO %T (phid, relatedPHID, relation) '. + ' VALUES %Q', + $rship_dao->getTableName(), + implode(', ', $sql)); + } + + } + +} diff --git a/src/applications/search/storage/document/document/__init__.php b/src/applications/search/storage/document/document/__init__.php new file mode 100644 index 0000000000..bae6063fde --- /dev/null +++ b/src/applications/search/storage/document/document/__init__.php @@ -0,0 +1,16 @@ + false, + self::CONFIG_IDS => self::IDS_MANUAL, + ) + parent::getConfiguration(); + } -require_once dirname(dirname(__FILE__)).'/conf/__init_conf__.php'; +} diff --git a/src/applications/search/storage/document/field/__init__.php b/src/applications/search/storage/document/field/__init__.php new file mode 100644 index 0000000000..b19d220da3 --- /dev/null +++ b/src/applications/search/storage/document/field/__init__.php @@ -0,0 +1,12 @@ + false, + self::CONFIG_IDS => self::IDS_MANUAL, + ) + parent::getConfiguration(); + } -require_once dirname(dirname(__FILE__)).'/conf/__init_conf__.php'; +} diff --git a/src/applications/search/storage/document/relationship/__init__.php b/src/applications/search/storage/document/relationship/__init__.php new file mode 100644 index 0000000000..1672a0d325 --- /dev/null +++ b/src/applications/search/storage/document/relationship/__init__.php @@ -0,0 +1,12 @@ + array( + 'parameters' => self::SERIALIZATION_JSON, + ), + ) + parent::getConfiguration(); + } -$conf = phabricator_read_config_file($env); -$conf['phabricator.env'] = $env; + public function setParameter($parameter, $value) { + $this->parameters[$parameter] = $value; + return $this; + } -phutil_require_module('phabricator', 'infrastructure/env'); -PhabricatorEnv::setEnvConfig($conf); -phutil_require_module('phutil', 'symbols'); + public function getParameter($parameter, $default = null) { + return idx($this->parameters, $parameter, $default); + } -PhutilSymbolLoader::loadClass('PhabricatorMetaMTADaemon'); -$daemon = new PhabricatorMetaMTADaemon(); -$daemon->run(); +} diff --git a/src/applications/search/storage/query/__init__.php b/src/applications/search/storage/query/__init__.php new file mode 100644 index 0000000000..9fee0d56db --- /dev/null +++ b/src/applications/search/storage/query/__init__.php @@ -0,0 +1,14 @@ + $v) { switch ($k) { case 'sigil': $attributes['data-sigil'] = $v; unset($attributes[$k]); break; case 'meta': $response = CelerityAPI::getStaticResourceResponse(); $id = $response->addMetadata($v); $attributes['data-meta'] = $id; unset($attributes[$k]); break; case 'mustcapture': $attributes['data-mustcapture'] = '1'; unset($attributes[$k]); break; } } } return phutil_render_tag($tag, $attributes, $content); } + + +function phabricator_render_form(PhabricatorUser $user, $attributes, $content) { + return javelin_render_tag( + 'form', + $attributes, + phutil_render_tag( + 'input', + array( + 'type' => 'hidden', + 'name' => '__csrf__', + 'value' => $user->getCSRFToken(), + )). + phutil_render_tag( + 'input', + array( + 'type' => 'hidden', + 'name' => '__form__', + 'value' => true, + )).$content); +} + diff --git a/src/view/page/standard/PhabricatorStandardPageView.php b/src/view/page/standard/PhabricatorStandardPageView.php index ef0ab6fcc4..b6320fd7f9 100755 --- a/src/view/page/standard/PhabricatorStandardPageView.php +++ b/src/view/page/standard/PhabricatorStandardPageView.php @@ -1,237 +1,240 @@ request = $request; return $this; } public function getRequest() { return $this->request; } public function setApplicationName($application_name) { $this->applicationName = $application_name; return $this; } public function getApplicationName() { return $this->applicationName; } public function setBaseURI($base_uri) { $this->baseURI = $base_uri; return $this; } public function getBaseURI() { return $this->baseURI; } public function setTabs(array $tabs, $selected_tab) { $this->tabs = $tabs; $this->selectedTab = $selected_tab; return $this; } public function getTitle() { return $this->getGlyph().' '.parent::getTitle(); } protected function willRenderPage() { if (!$this->getRequest()) { throw new Exception( "You must set the Request to render a PhabricatorStandardPageView."); } $console = $this->getRequest()->getApplicationConfiguration()->getConsole(); require_celerity_resource('phabricator-core-css'); require_celerity_resource('phabricator-core-buttons-css'); require_celerity_resource('phabricator-standard-page-view'); require_celerity_resource('javelin-lib-dev'); require_celerity_resource('javelin-workflow-dev'); Javelin::initBehavior('workflow', array()); if ($console) { require_celerity_resource('aphront-dark-console-css'); Javelin::initBehavior( 'dark-console', array( 'uri' => '/~/', )); } $this->bodyContent = $this->renderChildren(); } protected function getHead() { $response = CelerityAPI::getStaticResourceResponse(); return $response->renderResourcesOfType('css'). ''. ''; } public function setGlyph($glyph) { $this->glyph = $glyph; return $this; } public function getGlyph() { return $this->glyph; } protected function willSendResponse($response) { $console = $this->getRequest()->getApplicationConfiguration()->getConsole(); if ($console) { $response = str_replace( '', $console->render($this->getRequest()), $response); } return $response; } protected function getBody() { $console = $this->getRequest()->getApplicationConfiguration()->getConsole(); $tabs = array(); foreach ($this->tabs as $name => $tab) { $tabs[] = phutil_render_tag( 'a', array( 'href' => idx($tab, 'href'), 'class' => ($name == $this->selectedTab) ? 'phabricator-selected-tab' : null, ), phutil_escape_html(idx($tab, 'name'))); } $tabs = implode('', $tabs); if ($tabs) { $tabs = ''.$tabs.''; } $login_stuff = null; $request = $this->getRequest(); if ($request) { $user = $request->getUser(); if ($user->getPHID()) { $login_stuff = 'Logged in as '.phutil_escape_html($user->getUsername()). ' · '. 'Settings'. ' · '. - '
'. - phutil_render_tag( - 'input', - array( - 'type' => 'hidden', - 'name' => '__csrf__', - 'value' => $user->getCSRFToken(), - )). - phutil_render_tag( - 'input', - array( - 'type' => 'hidden', - 'name' => '__form__', - 'value' => true, - )). - ''. - '
'; + phabricator_render_form( + $user, + array( + 'action' => '/search/', + 'method' => 'post', + 'style' => 'display: inline', + ), + ''. + ''); } } $foot_links = array(); $version = PhabricatorEnv::getEnvConfig('phabricator.version'); $foot_links[] = phutil_escape_html('Phabricator '.$version); if (PhabricatorEnv::getEnvConfig('darkconsole.enabled') && !PhabricatorEnv::getEnvConfig('darkconsole.always-on')) { if ($console) { $link = javelin_render_tag( 'a', array( 'href' => '/~/', 'sigil' => 'workflow', ), 'Disable DarkConsole'); } else { $link = javelin_render_tag( 'a', array( 'href' => '/~/', 'sigil' => 'workflow', ), 'Enable DarkConsole'); } $foot_links[] = $link; } + // This ends up very early in tab order at the top of the page and there's + // a bunch of junk up there anyway, just shove it down here. + $foot_links[] = phabricator_render_form( + $user, + array( + 'action' => '/logout/', + 'method' => 'post', + 'style' => 'display: inline', + ), + ''); + $foot_links = implode(' · ', $foot_links); return ($console ? '' : null). '
'. '
'. ''. 'Phabricator '. phutil_render_tag( 'a', array( 'href' => $this->getBaseURI(), 'class' => 'phabricator-head-appname', ), phutil_escape_html($this->getApplicationName())). $tabs. '
'. $this->bodyContent. '
'. '
'. '
'. $foot_links. '
'; } protected function getTail() { $response = CelerityAPI::getStaticResourceResponse(); return $response->renderResourcesOfType('js'). $response->renderHTMLFooter(); } }