From 601aaa5a86c1d606b11f8c16ee908ef4bd077fd3 Mon Sep 17 00:00:00 2001 From: epriestley Date: Fri, 25 Mar 2016 05:56:16 -0700 Subject: [PATCH 01/42] Modularize content sources Summary: Ref T10537. For Nuance, I want to introduce new sources (like "GitHub" or "GitHub via Nuance" or something) but this needs to modularize eventually. Split ContentSource apart so applications can add new content sources. Test Plan: This change has huge surface area, so I'll hold it until post-release. I think it's fairly safe (and if it does break anything, the breaks should be fatals, not anything subtle or difficult to fix), there's just no reason not to hold it for a few hours. - Viewed new module page. - Grepped for all removed functions/constants. - Viewed some transactions. - Hovered over timestamps to get content source details. - Added a comment via Conduit. - Added a comment via web. - Ran `bin/storage upgrade --namespace XXXXX --no-quickstart -f` to re-run all historic migrations. - Generated some objects with `bin/lipsum`. - Ran a bulk job on some tasks. - Ran unit tests. {F1190182} Reviewers: chad Reviewed By: chad Maniphest Tasks: T10537 Differential Revision: https://secure.phabricator.com/D15521 --- .../20140211.dx.2.migcommenttext.php | 3 +- .../autopatches/20140212.dx.1.armageddon.php | 3 +- .../20140722.audit.3.miginlines.php | 3 +- .../autopatches/20140722.audit.4.migtext.php | 3 +- .../20140725.audit.1.migxactions.php | 3 +- .../sql/patches/20130715.votecomments.php | 5 +- .../sql/patches/20130728.ponderxcomment.php | 6 +- .../sql/patches/20130801.pastexactions.php | 3 +- resources/sql/patches/20130926.dinline.php | 3 +- .../sql/patches/20131020.pxactionmig.php | 3 +- src/__phutil_library_map__.php | 32 +++++- .../management/AlmanacManagementWorkflow.php | 3 +- .../storage/PhabricatorAuditInlineComment.php | 3 +- .../conduit/protocol/ConduitAPIRequest.php | 5 + .../__tests__/ConpherenceRoomTestCase.php | 4 +- .../__tests__/ConpherenceTestCase.php | 6 +- ...onpherenceCreateThreadConduitAPIMethod.php | 2 +- ...onpherenceUpdateThreadConduitAPIMethod.php | 2 +- .../mail/ConpherenceReplyHandler.php | 6 +- .../DifferentialCloseConduitAPIMethod.php | 6 +- .../conduit/DifferentialConduitAPIMethod.php | 2 +- ...ferentialCreateCommentConduitAPIMethod.php | 2 +- ...DifferentialCreateDiffConduitAPIMethod.php | 2 +- ...ferentialCreateRawDiffConduitAPIMethod.php | 2 +- ...icatorDifferentialAttachCommitWorkflow.php | 4 +- .../storage/DifferentialInlineComment.php | 3 +- ...DiffusionCreateCommentConduitAPIMethod.php | 2 +- .../engine/HarbormasterBuildEngine.php | 3 +- .../PhabricatorHeraldContentSource.php | 16 +++ .../herald/field/HeraldContentSourceField.php | 5 +- .../PhabricatorTestDataGenerator.php | 3 +- .../__tests__/ManiphestTaskTestCase.php | 2 +- .../conduit/ManiphestConduitAPIMethod.php | 4 +- ...bricatorManiphestTaskTestDataGenerator.php | 4 +- .../PhabricatorContentSource.php | 104 ------------------ .../PhabricatorEmailContentSource.php | 16 +++ .../PhabricatorMetaMTAReceivedMail.php | 8 ++ .../nuance/item/NuanceGitHubEventItemType.php | 5 +- .../nuance/item/NuanceItemType.php | 3 +- .../conduit/PasteCreateConduitAPIMethod.php | 2 +- .../paste/mail/PasteCreateMailReceiver.php | 7 +- ...PhabricatorPholioMockTestDataGenerator.php | 5 +- .../PhabricatorPhortuneContentSource.php | 16 +++ .../product/PhortuneProductImplementation.php | 3 +- .../phortune/storage/PhortuneCart.php | 3 +- .../worker/PhortuneSubscriptionWorker.php | 3 +- .../PhrictionCreateConduitAPIMethod.php | 2 +- .../conduit/PhrictionEditConduitAPIMethod.php | 2 +- .../PhabricatorProjectCoreTestCase.php | 8 +- .../conduit/ProjectCreateConduitAPIMethod.php | 2 +- .../ReleephRequestConduitAPIMethod.php | 5 +- .../ReleephWorkRecordConduitAPIMethod.php | 5 +- ...phWorkRecordPickStatusConduitAPIMethod.php | 5 +- ...entialReleephRequestFieldSpecification.php | 3 +- ...icatorRepositoryManagementEditWorkflow.php | 2 +- ...habricatorRepositoryCommitHeraldWorker.php | 4 +- ...torRepositoryCommitMessageParserWorker.php | 8 +- .../__tests__/PhabricatorSpacesTestCase.php | 2 +- .../conduit/TokenGiveConduitAPIMethod.php | 2 +- ...icationTransactionCommentRawController.php | 4 +- .../editengine/PhabricatorEditEngine.php | 2 +- ...habricatorApplicationTransactionEditor.php | 13 +-- ...atorApplicationTransactionReplyHandler.php | 6 +- ...torApplicationTransactionPublishWorker.php | 4 +- .../PhabricatorConduitContentSource.php | 16 +++ .../PhabricatorConsoleContentSource.php | 16 +++ .../PhabricatorContentSource.php | 92 ++++++++++++++++ .../PhabricatorContentSourceModule.php | 51 +++++++++ .../PhabricatorContentSourceView.php | 15 +-- .../PhabricatorFaxContentSource.php | 16 +++ .../PhabricatorLipsumContentSource.php | 16 +++ .../PhabricatorOldWorldContentSource.php | 17 +++ .../PhabricatorUnitTestContentSource.php | 16 +++ .../PhabricatorUnknownContentSource.php | 21 ++++ .../PhabricatorWebContentSource.php | 16 +++ .../PhabricatorBulkContentSource.php | 16 +++ .../PhabricatorDaemonContentSource.php | 16 +++ .../daemon/workers/PhabricatorWorker.php | 5 + .../bulk/PhabricatorWorkerBulkJobWorker.php | 4 +- .../storage/PhabricatorWorkerBulkJob.php | 2 +- .../PhabricatorManagementWorkflow.php | 5 + .../testing/PhabricatorTestCase.php | 4 + src/view/phui/PHUITimelineEventView.php | 4 +- 83 files changed, 495 insertions(+), 265 deletions(-) create mode 100644 src/applications/herald/contentsource/PhabricatorHeraldContentSource.php delete mode 100644 src/applications/metamta/contentsource/PhabricatorContentSource.php create mode 100644 src/applications/metamta/contentsource/PhabricatorEmailContentSource.php create mode 100644 src/applications/phortune/contentsource/PhabricatorPhortuneContentSource.php create mode 100644 src/infrastructure/contentsource/PhabricatorConduitContentSource.php create mode 100644 src/infrastructure/contentsource/PhabricatorConsoleContentSource.php create mode 100644 src/infrastructure/contentsource/PhabricatorContentSource.php create mode 100644 src/infrastructure/contentsource/PhabricatorContentSourceModule.php rename src/{applications/metamta => infrastructure}/contentsource/PhabricatorContentSourceView.php (61%) create mode 100644 src/infrastructure/contentsource/PhabricatorFaxContentSource.php create mode 100644 src/infrastructure/contentsource/PhabricatorLipsumContentSource.php create mode 100644 src/infrastructure/contentsource/PhabricatorOldWorldContentSource.php create mode 100644 src/infrastructure/contentsource/PhabricatorUnitTestContentSource.php create mode 100644 src/infrastructure/contentsource/PhabricatorUnknownContentSource.php create mode 100644 src/infrastructure/contentsource/PhabricatorWebContentSource.php create mode 100644 src/infrastructure/daemon/contentsource/PhabricatorBulkContentSource.php create mode 100644 src/infrastructure/daemon/contentsource/PhabricatorDaemonContentSource.php diff --git a/resources/sql/autopatches/20140211.dx.2.migcommenttext.php b/resources/sql/autopatches/20140211.dx.2.migcommenttext.php index 705e858069..7c531f51f8 100644 --- a/resources/sql/autopatches/20140211.dx.2.migcommenttext.php +++ b/resources/sql/autopatches/20140211.dx.2.migcommenttext.php @@ -4,8 +4,7 @@ $conn_w = id(new DifferentialRevision())->establishConnection('w'); $rows = new LiskRawMigrationIterator($conn_w, 'differential_comment'); $content_source = PhabricatorContentSource::newForSource( - PhabricatorContentSource::SOURCE_LEGACY, - array())->serialize(); + PhabricatorOldWorldContentSource::SOURCECONST)->serialize(); echo pht('Migrating Differential comment text to modern storage...')."\n"; foreach ($rows as $row) { diff --git a/resources/sql/autopatches/20140212.dx.1.armageddon.php b/resources/sql/autopatches/20140212.dx.1.armageddon.php index d2749bd5cf..021e886629 100644 --- a/resources/sql/autopatches/20140212.dx.1.armageddon.php +++ b/resources/sql/autopatches/20140212.dx.1.armageddon.php @@ -4,8 +4,7 @@ $conn_w = id(new DifferentialRevision())->establishConnection('w'); $rows = new LiskRawMigrationIterator($conn_w, 'differential_comment'); $content_source = PhabricatorContentSource::newForSource( - PhabricatorContentSource::SOURCE_LEGACY, - array())->serialize(); + PhabricatorOldWorldContentSource::SOURCECONST)->serialize(); echo pht('Migrating Differential comments to modern storage...')."\n"; foreach ($rows as $row) { diff --git a/resources/sql/autopatches/20140722.audit.3.miginlines.php b/resources/sql/autopatches/20140722.audit.3.miginlines.php index c6778fa659..d816b534eb 100644 --- a/resources/sql/autopatches/20140722.audit.3.miginlines.php +++ b/resources/sql/autopatches/20140722.audit.3.miginlines.php @@ -10,8 +10,7 @@ $dst_table = 'audit_transaction_comment'; echo pht('Migrating Audit inline comments to new format...')."\n"; $content_source = PhabricatorContentSource::newForSource( - PhabricatorContentSource::SOURCE_LEGACY, - array())->serialize(); + PhabricatorOldWorldContentSource::SOURCECONST)->serialize(); $rows = new LiskRawMigrationIterator($conn_w, $src_table); foreach ($rows as $row) { diff --git a/resources/sql/autopatches/20140722.audit.4.migtext.php b/resources/sql/autopatches/20140722.audit.4.migtext.php index 2da4e2683e..c2a775058b 100644 --- a/resources/sql/autopatches/20140722.audit.4.migtext.php +++ b/resources/sql/autopatches/20140722.audit.4.migtext.php @@ -4,8 +4,7 @@ $conn_w = id(new PhabricatorAuditTransaction())->establishConnection('w'); $rows = new LiskRawMigrationIterator($conn_w, 'audit_comment'); $content_source = PhabricatorContentSource::newForSource( - PhabricatorContentSource::SOURCE_LEGACY, - array())->serialize(); + PhabricatorOldWorldContentSource::SOURCECONST)->serialize(); echo pht('Migrating Audit comment text to modern storage...')."\n"; foreach ($rows as $row) { diff --git a/resources/sql/autopatches/20140725.audit.1.migxactions.php b/resources/sql/autopatches/20140725.audit.1.migxactions.php index e0e14e439b..4eb0897aeb 100644 --- a/resources/sql/autopatches/20140725.audit.1.migxactions.php +++ b/resources/sql/autopatches/20140725.audit.1.migxactions.php @@ -4,8 +4,7 @@ $conn_w = id(new PhabricatorAuditTransaction())->establishConnection('w'); $rows = new LiskRawMigrationIterator($conn_w, 'audit_comment'); $content_source = PhabricatorContentSource::newForSource( - PhabricatorContentSource::SOURCE_LEGACY, - array())->serialize(); + PhabricatorOldWorldContentSource::SOURCECONST)->serialize(); echo pht('Migrating Audit comments to modern storage...')."\n"; foreach ($rows as $row) { diff --git a/resources/sql/patches/20130715.votecomments.php b/resources/sql/patches/20130715.votecomments.php index 0d540596b3..1066126318 100644 --- a/resources/sql/patches/20130715.votecomments.php +++ b/resources/sql/patches/20130715.votecomments.php @@ -46,9 +46,8 @@ foreach ($comments as $comment) { PhabricatorApplicationTransactionTransactionPHIDType::TYPECONST, PhabricatorSlowvotePollPHIDType::TYPECONST); - $source = PhabricatorContentSource::newForSource( - PhabricatorContentSource::SOURCE_LEGACY, - array())->serialize(); + $content_source = PhabricatorContentSource::newForSource( + PhabricatorOldWorldContentSource::SOURCECONST)->serialize(); queryfx( $conn_w, diff --git a/resources/sql/patches/20130728.ponderxcomment.php b/resources/sql/patches/20130728.ponderxcomment.php index 92e858f95e..9a7413e351 100644 --- a/resources/sql/patches/20130728.ponderxcomment.php +++ b/resources/sql/patches/20130728.ponderxcomment.php @@ -49,8 +49,7 @@ foreach ($rows as $row) { 1, $row['content'], PhabricatorContentSource::newForSource( - PhabricatorContentSource::SOURCE_LEGACY, - array())->serialize(), + PhabricatorOldWorldContentSource::SOURCECONST)->serialize(), 0, $row['dateCreated'], $row['dateModified']); @@ -73,8 +72,7 @@ foreach ($rows as $row) { 'null', 'null', PhabricatorContentSource::newForSource( - PhabricatorContentSource::SOURCE_LEGACY, - array())->serialize(), + PhabricatorOldWorldContentSource::SOURCECONST)->serialize(), '[]', $row['dateCreated'], $row['dateModified']); diff --git a/resources/sql/patches/20130801.pastexactions.php b/resources/sql/patches/20130801.pastexactions.php index 1977eb984e..75c2ece940 100644 --- a/resources/sql/patches/20130801.pastexactions.php +++ b/resources/sql/patches/20130801.pastexactions.php @@ -34,8 +34,7 @@ foreach ($rows as $row) { 'null', $row['filePHID'], PhabricatorContentSource::newForSource( - PhabricatorContentSource::SOURCE_LEGACY, - array())->serialize(), + PhabricatorOldWorldContentSource::SOURCECONST)->serialize(), '[]', $row['dateCreated'], $row['dateCreated'], diff --git a/resources/sql/patches/20130926.dinline.php b/resources/sql/patches/20130926.dinline.php index f2d9e9f205..7b67adc9b7 100644 --- a/resources/sql/patches/20130926.dinline.php +++ b/resources/sql/patches/20130926.dinline.php @@ -10,8 +10,7 @@ $dst_table = 'differential_transaction_comment'; echo pht('Migrating Differential inline comments to new format...')."\n"; $content_source = PhabricatorContentSource::newForSource( - PhabricatorContentSource::SOURCE_LEGACY, - array())->serialize(); + PhabricatorOldWorldContentSource::SOURCECONST)->serialize(); $rows = new LiskRawMigrationIterator($conn_w, $src_table); foreach ($rows as $row) { diff --git a/resources/sql/patches/20131020.pxactionmig.php b/resources/sql/patches/20131020.pxactionmig.php index 7bf4416cd0..3d593d6e34 100644 --- a/resources/sql/patches/20131020.pxactionmig.php +++ b/resources/sql/patches/20131020.pxactionmig.php @@ -10,8 +10,7 @@ $dst_table = 'project_transaction'; echo pht('Migrating Project transactions to new format...')."\n"; $content_source = PhabricatorContentSource::newForSource( - PhabricatorContentSource::SOURCE_LEGACY, - array())->serialize(); + PhabricatorOldWorldContentSource::SOURCECONST)->serialize(); $rows = new LiskRawMigrationIterator($conn_w, $src_table); foreach ($rows as $row) { diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php index c4771045bb..150d2bd8cd 100644 --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -1919,6 +1919,7 @@ phutil_register_library_map(array( 'PhabricatorBotWhatsNewHandler' => 'infrastructure/daemon/bot/handler/PhabricatorBotWhatsNewHandler.php', 'PhabricatorBritishEnglishTranslation' => 'infrastructure/internationalization/translation/PhabricatorBritishEnglishTranslation.php', 'PhabricatorBuiltinPatchList' => 'infrastructure/storage/patch/PhabricatorBuiltinPatchList.php', + 'PhabricatorBulkContentSource' => 'infrastructure/daemon/contentsource/PhabricatorBulkContentSource.php', 'PhabricatorBusyUIExample' => 'applications/uiexample/examples/PhabricatorBusyUIExample.php', 'PhabricatorCacheDAO' => 'applications/cache/storage/PhabricatorCacheDAO.php', 'PhabricatorCacheGeneralGarbageCollector' => 'applications/cache/garbagecollector/PhabricatorCacheGeneralGarbageCollector.php', @@ -1993,6 +1994,7 @@ phutil_register_library_map(array( 'PhabricatorConduitCertificateToken' => 'applications/conduit/storage/PhabricatorConduitCertificateToken.php', 'PhabricatorConduitConnectionLog' => 'applications/conduit/storage/PhabricatorConduitConnectionLog.php', 'PhabricatorConduitConsoleController' => 'applications/conduit/controller/PhabricatorConduitConsoleController.php', + 'PhabricatorConduitContentSource' => 'infrastructure/contentsource/PhabricatorConduitContentSource.php', 'PhabricatorConduitController' => 'applications/conduit/controller/PhabricatorConduitController.php', 'PhabricatorConduitDAO' => 'applications/conduit/storage/PhabricatorConduitDAO.php', 'PhabricatorConduitEditField' => 'applications/transactions/editfield/PhabricatorConduitEditField.php', @@ -2080,8 +2082,10 @@ phutil_register_library_map(array( 'PhabricatorConpherencePreferencesSettingsPanel' => 'applications/settings/panel/PhabricatorConpherencePreferencesSettingsPanel.php', 'PhabricatorConpherenceThreadPHIDType' => 'applications/conpherence/phid/PhabricatorConpherenceThreadPHIDType.php', 'PhabricatorConsoleApplication' => 'applications/console/application/PhabricatorConsoleApplication.php', - 'PhabricatorContentSource' => 'applications/metamta/contentsource/PhabricatorContentSource.php', - 'PhabricatorContentSourceView' => 'applications/metamta/contentsource/PhabricatorContentSourceView.php', + 'PhabricatorConsoleContentSource' => 'infrastructure/contentsource/PhabricatorConsoleContentSource.php', + 'PhabricatorContentSource' => 'infrastructure/contentsource/PhabricatorContentSource.php', + 'PhabricatorContentSourceModule' => 'infrastructure/contentsource/PhabricatorContentSourceModule.php', + 'PhabricatorContentSourceView' => 'infrastructure/contentsource/PhabricatorContentSourceView.php', 'PhabricatorContributedToObjectEdgeType' => 'applications/transactions/edges/PhabricatorContributedToObjectEdgeType.php', 'PhabricatorController' => 'applications/base/controller/PhabricatorController.php', 'PhabricatorCookies' => 'applications/auth/constants/PhabricatorCookies.php', @@ -2138,6 +2142,7 @@ phutil_register_library_map(array( 'PhabricatorDaemonBulkJobMonitorController' => 'applications/daemon/controller/PhabricatorDaemonBulkJobMonitorController.php', 'PhabricatorDaemonBulkJobViewController' => 'applications/daemon/controller/PhabricatorDaemonBulkJobViewController.php', 'PhabricatorDaemonConsoleController' => 'applications/daemon/controller/PhabricatorDaemonConsoleController.php', + 'PhabricatorDaemonContentSource' => 'infrastructure/daemon/contentsource/PhabricatorDaemonContentSource.php', 'PhabricatorDaemonController' => 'applications/daemon/controller/PhabricatorDaemonController.php', 'PhabricatorDaemonDAO' => 'applications/daemon/storage/PhabricatorDaemonDAO.php', 'PhabricatorDaemonEventListener' => 'applications/daemon/event/PhabricatorDaemonEventListener.php', @@ -2302,6 +2307,7 @@ phutil_register_library_map(array( 'PhabricatorElasticFulltextStorageEngine' => 'applications/search/fulltextstorage/PhabricatorElasticFulltextStorageEngine.php', 'PhabricatorElasticSearchSetupCheck' => 'applications/config/check/PhabricatorElasticSearchSetupCheck.php', 'PhabricatorEmailAddressesSettingsPanel' => 'applications/settings/panel/PhabricatorEmailAddressesSettingsPanel.php', + 'PhabricatorEmailContentSource' => 'applications/metamta/contentsource/PhabricatorEmailContentSource.php', 'PhabricatorEmailFormatSettingsPanel' => 'applications/settings/panel/PhabricatorEmailFormatSettingsPanel.php', 'PhabricatorEmailLoginController' => 'applications/auth/controller/PhabricatorEmailLoginController.php', 'PhabricatorEmailPreferencesSettingsPanel' => 'applications/settings/panel/PhabricatorEmailPreferencesSettingsPanel.php', @@ -2347,6 +2353,7 @@ phutil_register_library_map(array( 'PhabricatorFactSimpleSpec' => 'applications/fact/spec/PhabricatorFactSimpleSpec.php', 'PhabricatorFactSpec' => 'applications/fact/spec/PhabricatorFactSpec.php', 'PhabricatorFactUpdateIterator' => 'applications/fact/extract/PhabricatorFactUpdateIterator.php', + 'PhabricatorFaxContentSource' => 'infrastructure/contentsource/PhabricatorFaxContentSource.php', 'PhabricatorFeedApplication' => 'applications/feed/application/PhabricatorFeedApplication.php', 'PhabricatorFeedBuilder' => 'applications/feed/builder/PhabricatorFeedBuilder.php', 'PhabricatorFeedConfigOptions' => 'applications/feed/config/PhabricatorFeedConfigOptions.php', @@ -2476,6 +2483,7 @@ phutil_register_library_map(array( 'PhabricatorHelpKeyboardShortcutController' => 'applications/help/controller/PhabricatorHelpKeyboardShortcutController.php', 'PhabricatorHelpMainMenuBarExtension' => 'applications/help/extension/PhabricatorHelpMainMenuBarExtension.php', 'PhabricatorHeraldApplication' => 'applications/herald/application/PhabricatorHeraldApplication.php', + 'PhabricatorHeraldContentSource' => 'applications/herald/contentsource/PhabricatorHeraldContentSource.php', 'PhabricatorHighSecurityRequestExceptionHandler' => 'aphront/handler/PhabricatorHighSecurityRequestExceptionHandler.php', 'PhabricatorHomeApplication' => 'applications/home/application/PhabricatorHomeApplication.php', 'PhabricatorHomeController' => 'applications/home/controller/PhabricatorHomeController.php', @@ -2524,6 +2532,7 @@ phutil_register_library_map(array( 'PhabricatorLibraryTestCase' => '__tests__/PhabricatorLibraryTestCase.php', 'PhabricatorLinkProfilePanel' => 'applications/search/profilepanel/PhabricatorLinkProfilePanel.php', 'PhabricatorLipsumArtist' => 'applications/lipsum/image/PhabricatorLipsumArtist.php', + 'PhabricatorLipsumContentSource' => 'infrastructure/contentsource/PhabricatorLipsumContentSource.php', 'PhabricatorLipsumGenerateWorkflow' => 'applications/lipsum/management/PhabricatorLipsumGenerateWorkflow.php', 'PhabricatorLipsumManagementWorkflow' => 'applications/lipsum/management/PhabricatorLipsumManagementWorkflow.php', 'PhabricatorLipsumMondrianArtist' => 'applications/lipsum/image/PhabricatorLipsumMondrianArtist.php', @@ -2737,6 +2746,7 @@ phutil_register_library_map(array( 'PhabricatorObjectSelectorDialog' => 'view/control/PhabricatorObjectSelectorDialog.php', 'PhabricatorObjectUsesCredentialsEdgeType' => 'applications/transactions/edges/PhabricatorObjectUsesCredentialsEdgeType.php', 'PhabricatorOffsetPagedQuery' => 'infrastructure/query/PhabricatorOffsetPagedQuery.php', + 'PhabricatorOldWorldContentSource' => 'infrastructure/contentsource/PhabricatorOldWorldContentSource.php', 'PhabricatorOneTimeTriggerClock' => 'infrastructure/daemon/workers/clock/PhabricatorOneTimeTriggerClock.php', 'PhabricatorOpcodeCacheSpec' => 'applications/cache/spec/PhabricatorOpcodeCacheSpec.php', 'PhabricatorOwnerPathQuery' => 'applications/owners/query/PhabricatorOwnerPathQuery.php', @@ -2871,6 +2881,7 @@ phutil_register_library_map(array( 'PhabricatorPholioConfigOptions' => 'applications/pholio/config/PhabricatorPholioConfigOptions.php', 'PhabricatorPholioMockTestDataGenerator' => 'applications/pholio/lipsum/PhabricatorPholioMockTestDataGenerator.php', 'PhabricatorPhortuneApplication' => 'applications/phortune/application/PhabricatorPhortuneApplication.php', + 'PhabricatorPhortuneContentSource' => 'applications/phortune/contentsource/PhabricatorPhortuneContentSource.php', 'PhabricatorPhortuneManagementInvoiceWorkflow' => 'applications/phortune/management/PhabricatorPhortuneManagementInvoiceWorkflow.php', 'PhabricatorPhortuneManagementWorkflow' => 'applications/phortune/management/PhabricatorPhortuneManagementWorkflow.php', 'PhabricatorPhragmentApplication' => 'applications/phragment/application/PhabricatorPhragmentApplication.php', @@ -3471,7 +3482,9 @@ phutil_register_library_map(array( 'PhabricatorUIExampleRenderController' => 'applications/uiexample/controller/PhabricatorUIExampleRenderController.php', 'PhabricatorUIExamplesApplication' => 'applications/uiexample/application/PhabricatorUIExamplesApplication.php', 'PhabricatorUSEnglishTranslation' => 'infrastructure/internationalization/translation/PhabricatorUSEnglishTranslation.php', + 'PhabricatorUnitTestContentSource' => 'infrastructure/contentsource/PhabricatorUnitTestContentSource.php', 'PhabricatorUnitsTestCase' => 'view/__tests__/PhabricatorUnitsTestCase.php', + 'PhabricatorUnknownContentSource' => 'infrastructure/contentsource/PhabricatorUnknownContentSource.php', 'PhabricatorUnsubscribedFromObjectEdgeType' => 'applications/transactions/edges/PhabricatorUnsubscribedFromObjectEdgeType.php', 'PhabricatorUser' => 'applications/people/storage/PhabricatorUser.php', 'PhabricatorUserBlurbField' => 'applications/people/customfield/PhabricatorUserBlurbField.php', @@ -3511,6 +3524,7 @@ phutil_register_library_map(array( 'PhabricatorVeryWowEnglishTranslation' => 'infrastructure/internationalization/translation/PhabricatorVeryWowEnglishTranslation.php', 'PhabricatorViewerDatasource' => 'applications/people/typeahead/PhabricatorViewerDatasource.php', 'PhabricatorWatcherHasObjectEdgeType' => 'applications/transactions/edges/PhabricatorWatcherHasObjectEdgeType.php', + 'PhabricatorWebContentSource' => 'infrastructure/contentsource/PhabricatorWebContentSource.php', 'PhabricatorWordPressAuthProvider' => 'applications/auth/provider/PhabricatorWordPressAuthProvider.php', 'PhabricatorWorker' => 'infrastructure/daemon/workers/PhabricatorWorker.php', 'PhabricatorWorkerActiveTask' => 'infrastructure/daemon/workers/storage/PhabricatorWorkerActiveTask.php', @@ -6274,6 +6288,7 @@ phutil_register_library_map(array( 'PhabricatorBotWhatsNewHandler' => 'PhabricatorBotHandler', 'PhabricatorBritishEnglishTranslation' => 'PhutilTranslation', 'PhabricatorBuiltinPatchList' => 'PhabricatorSQLPatchList', + 'PhabricatorBulkContentSource' => 'PhabricatorContentSource', 'PhabricatorBusyUIExample' => 'PhabricatorUIExample', 'PhabricatorCacheDAO' => 'PhabricatorLiskDAO', 'PhabricatorCacheGeneralGarbageCollector' => 'PhabricatorGarbageCollector', @@ -6369,6 +6384,7 @@ phutil_register_library_map(array( 'PhabricatorConduitCertificateToken' => 'PhabricatorConduitDAO', 'PhabricatorConduitConnectionLog' => 'PhabricatorConduitDAO', 'PhabricatorConduitConsoleController' => 'PhabricatorConduitController', + 'PhabricatorConduitContentSource' => 'PhabricatorContentSource', 'PhabricatorConduitController' => 'PhabricatorController', 'PhabricatorConduitDAO' => 'PhabricatorLiskDAO', 'PhabricatorConduitEditField' => 'PhabricatorEditField', @@ -6469,7 +6485,9 @@ phutil_register_library_map(array( 'PhabricatorConpherencePreferencesSettingsPanel' => 'PhabricatorSettingsPanel', 'PhabricatorConpherenceThreadPHIDType' => 'PhabricatorPHIDType', 'PhabricatorConsoleApplication' => 'PhabricatorApplication', + 'PhabricatorConsoleContentSource' => 'PhabricatorContentSource', 'PhabricatorContentSource' => 'Phobject', + 'PhabricatorContentSourceModule' => 'PhabricatorConfigModule', 'PhabricatorContentSourceView' => 'AphrontView', 'PhabricatorContributedToObjectEdgeType' => 'PhabricatorEdgeType', 'PhabricatorController' => 'AphrontController', @@ -6535,6 +6553,7 @@ phutil_register_library_map(array( 'PhabricatorDaemonBulkJobMonitorController' => 'PhabricatorDaemonController', 'PhabricatorDaemonBulkJobViewController' => 'PhabricatorDaemonController', 'PhabricatorDaemonConsoleController' => 'PhabricatorDaemonController', + 'PhabricatorDaemonContentSource' => 'PhabricatorContentSource', 'PhabricatorDaemonController' => 'PhabricatorController', 'PhabricatorDaemonDAO' => 'PhabricatorLiskDAO', 'PhabricatorDaemonEventListener' => 'PhabricatorEventListener', @@ -6726,6 +6745,7 @@ phutil_register_library_map(array( 'PhabricatorElasticFulltextStorageEngine' => 'PhabricatorFulltextStorageEngine', 'PhabricatorElasticSearchSetupCheck' => 'PhabricatorSetupCheck', 'PhabricatorEmailAddressesSettingsPanel' => 'PhabricatorSettingsPanel', + 'PhabricatorEmailContentSource' => 'PhabricatorContentSource', 'PhabricatorEmailFormatSettingsPanel' => 'PhabricatorSettingsPanel', 'PhabricatorEmailLoginController' => 'PhabricatorAuthController', 'PhabricatorEmailPreferencesSettingsPanel' => 'PhabricatorSettingsPanel', @@ -6773,6 +6793,7 @@ phutil_register_library_map(array( 'PhabricatorFactSimpleSpec' => 'PhabricatorFactSpec', 'PhabricatorFactSpec' => 'Phobject', 'PhabricatorFactUpdateIterator' => 'PhutilBufferedIterator', + 'PhabricatorFaxContentSource' => 'PhabricatorContentSource', 'PhabricatorFeedApplication' => 'PhabricatorApplication', 'PhabricatorFeedBuilder' => 'Phobject', 'PhabricatorFeedConfigOptions' => 'PhabricatorApplicationConfigOptions', @@ -6935,6 +6956,7 @@ phutil_register_library_map(array( 'PhabricatorHelpKeyboardShortcutController' => 'PhabricatorHelpController', 'PhabricatorHelpMainMenuBarExtension' => 'PhabricatorMainMenuBarExtension', 'PhabricatorHeraldApplication' => 'PhabricatorApplication', + 'PhabricatorHeraldContentSource' => 'PhabricatorContentSource', 'PhabricatorHighSecurityRequestExceptionHandler' => 'PhabricatorRequestExceptionHandler', 'PhabricatorHomeApplication' => 'PhabricatorApplication', 'PhabricatorHomeController' => 'PhabricatorController', @@ -6983,6 +7005,7 @@ phutil_register_library_map(array( 'PhabricatorLibraryTestCase' => 'PhutilLibraryTestCase', 'PhabricatorLinkProfilePanel' => 'PhabricatorProfilePanel', 'PhabricatorLipsumArtist' => 'Phobject', + 'PhabricatorLipsumContentSource' => 'PhabricatorContentSource', 'PhabricatorLipsumGenerateWorkflow' => 'PhabricatorLipsumManagementWorkflow', 'PhabricatorLipsumManagementWorkflow' => 'PhabricatorManagementWorkflow', 'PhabricatorLipsumMondrianArtist' => 'PhabricatorLipsumArtist', @@ -7218,6 +7241,7 @@ phutil_register_library_map(array( 'PhabricatorObjectSelectorDialog' => 'Phobject', 'PhabricatorObjectUsesCredentialsEdgeType' => 'PhabricatorEdgeType', 'PhabricatorOffsetPagedQuery' => 'PhabricatorQuery', + 'PhabricatorOldWorldContentSource' => 'PhabricatorContentSource', 'PhabricatorOneTimeTriggerClock' => 'PhabricatorTriggerClock', 'PhabricatorOpcodeCacheSpec' => 'PhabricatorCacheSpec', 'PhabricatorOwnerPathQuery' => 'Phobject', @@ -7375,6 +7399,7 @@ phutil_register_library_map(array( 'PhabricatorPholioConfigOptions' => 'PhabricatorApplicationConfigOptions', 'PhabricatorPholioMockTestDataGenerator' => 'PhabricatorTestDataGenerator', 'PhabricatorPhortuneApplication' => 'PhabricatorApplication', + 'PhabricatorPhortuneContentSource' => 'PhabricatorContentSource', 'PhabricatorPhortuneManagementInvoiceWorkflow' => 'PhabricatorPhortuneManagementWorkflow', 'PhabricatorPhortuneManagementWorkflow' => 'PhabricatorManagementWorkflow', 'PhabricatorPhragmentApplication' => 'PhabricatorApplication', @@ -8094,7 +8119,9 @@ phutil_register_library_map(array( 'PhabricatorUIExampleRenderController' => 'PhabricatorController', 'PhabricatorUIExamplesApplication' => 'PhabricatorApplication', 'PhabricatorUSEnglishTranslation' => 'PhutilTranslation', + 'PhabricatorUnitTestContentSource' => 'PhabricatorContentSource', 'PhabricatorUnitsTestCase' => 'PhabricatorTestCase', + 'PhabricatorUnknownContentSource' => 'PhabricatorContentSource', 'PhabricatorUnsubscribedFromObjectEdgeType' => 'PhabricatorEdgeType', 'PhabricatorUser' => array( 'PhabricatorUserDAO', @@ -8150,6 +8177,7 @@ phutil_register_library_map(array( 'PhabricatorVeryWowEnglishTranslation' => 'PhutilTranslation', 'PhabricatorViewerDatasource' => 'PhabricatorTypeaheadDatasource', 'PhabricatorWatcherHasObjectEdgeType' => 'PhabricatorEdgeType', + 'PhabricatorWebContentSource' => 'PhabricatorContentSource', 'PhabricatorWordPressAuthProvider' => 'PhabricatorOAuth2AuthProvider', 'PhabricatorWorker' => 'Phobject', 'PhabricatorWorkerActiveTask' => 'PhabricatorWorkerTask', diff --git a/src/applications/almanac/management/AlmanacManagementWorkflow.php b/src/applications/almanac/management/AlmanacManagementWorkflow.php index 840bc8b972..0f1dd6d773 100644 --- a/src/applications/almanac/management/AlmanacManagementWorkflow.php +++ b/src/applications/almanac/management/AlmanacManagementWorkflow.php @@ -3,7 +3,6 @@ abstract class AlmanacManagementWorkflow extends PhabricatorManagementWorkflow { - protected function loadServices(array $names) { if (!$names) { return array(); @@ -37,7 +36,7 @@ abstract class AlmanacManagementWorkflow $editor = id(new AlmanacServiceEditor()) ->setActor($this->getViewer()) ->setActingAsPHID($almanac_phid) - ->setContentSource(PhabricatorContentSource::newConsoleSource()) + ->setContentSource($this->newContentSource()) ->setContinueOnMissingFields(true); $editor->applyTransactions($service, array($xaction)); diff --git a/src/applications/audit/storage/PhabricatorAuditInlineComment.php b/src/applications/audit/storage/PhabricatorAuditInlineComment.php index fc28bce720..ecb627efec 100644 --- a/src/applications/audit/storage/PhabricatorAuditInlineComment.php +++ b/src/applications/audit/storage/PhabricatorAuditInlineComment.php @@ -34,8 +34,7 @@ final class PhabricatorAuditInlineComment public function getTransactionCommentForSave() { $content_source = PhabricatorContentSource::newForSource( - PhabricatorContentSource::SOURCE_LEGACY, - array()); + PhabricatorOldWorldContentSource::SOURCECONST); $this->proxy ->setViewPolicy('public') diff --git a/src/applications/conduit/protocol/ConduitAPIRequest.php b/src/applications/conduit/protocol/ConduitAPIRequest.php index 831c9de43e..3e322fcb32 100644 --- a/src/applications/conduit/protocol/ConduitAPIRequest.php +++ b/src/applications/conduit/protocol/ConduitAPIRequest.php @@ -57,4 +57,9 @@ final class ConduitAPIRequest extends Phobject { return $this->isClusterRequest; } + public function newContentSource() { + return PhabricatorContentSource::newForSource( + PhabricatorConduitContentSource::SOURCECONST); + } + } diff --git a/src/applications/conpherence/__tests__/ConpherenceRoomTestCase.php b/src/applications/conpherence/__tests__/ConpherenceRoomTestCase.php index 03dd615481..a4eeb3ed86 100644 --- a/src/applications/conpherence/__tests__/ConpherenceRoomTestCase.php +++ b/src/applications/conpherence/__tests__/ConpherenceRoomTestCase.php @@ -147,7 +147,7 @@ final class ConpherenceRoomTestCase extends ConpherenceTestCase { id(new ConpherenceEditor()) ->setActor($creator) - ->setContentSource(PhabricatorContentSource::newConsoleSource()) + ->setContentSource($this->newContentSource()) ->setContinueOnNoEffect(true) ->applyTransactions($conpherence, $xactions); @@ -166,7 +166,7 @@ final class ConpherenceRoomTestCase extends ConpherenceTestCase { id(new ConpherenceEditor()) ->setActor($actor) - ->setContentSource(PhabricatorContentSource::newConsoleSource()) + ->setContentSource($this->newContentSource()) ->setContinueOnNoEffect(true) ->applyTransactions($room, $xactions); } diff --git a/src/applications/conpherence/__tests__/ConpherenceTestCase.php b/src/applications/conpherence/__tests__/ConpherenceTestCase.php index ce9dc8ceee..1ad87d8af8 100644 --- a/src/applications/conpherence/__tests__/ConpherenceTestCase.php +++ b/src/applications/conpherence/__tests__/ConpherenceTestCase.php @@ -14,7 +14,7 @@ abstract class ConpherenceTestCase extends PhabricatorTestCase { ); $editor = id(new ConpherenceEditor()) ->setActor($actor) - ->setContentSource(PhabricatorContentSource::newConsoleSource()) + ->setContentSource($this->newContentSource()) ->applyTransactions($conpherence, $xactions); } @@ -31,7 +31,7 @@ abstract class ConpherenceTestCase extends PhabricatorTestCase { ); $editor = id(new ConpherenceEditor()) ->setActor($actor) - ->setContentSource(PhabricatorContentSource::newConsoleSource()) + ->setContentSource($this->newContentSource()) ->applyTransactions($conpherence, $xactions); } @@ -45,7 +45,7 @@ abstract class ConpherenceTestCase extends PhabricatorTestCase { $editor = id(new ConpherenceEditor()) ->setActor($actor) - ->setContentSource(PhabricatorContentSource::newConsoleSource()); + ->setContentSource($this->newContentSource()); $xactions = $editor->generateTransactionsFromText( $actor, diff --git a/src/applications/conpherence/conduit/ConpherenceCreateThreadConduitAPIMethod.php b/src/applications/conpherence/conduit/ConpherenceCreateThreadConduitAPIMethod.php index d58b11ffa5..30540bf242 100644 --- a/src/applications/conpherence/conduit/ConpherenceCreateThreadConduitAPIMethod.php +++ b/src/applications/conpherence/conduit/ConpherenceCreateThreadConduitAPIMethod.php @@ -42,7 +42,7 @@ final class ConpherenceCreateThreadConduitAPIMethod $participant_phids, $title, $message, - PhabricatorContentSource::newFromConduitRequest($request)); + $request->newContentSource()); if ($errors) { foreach ($errors as $error_code) { diff --git a/src/applications/conpherence/conduit/ConpherenceUpdateThreadConduitAPIMethod.php b/src/applications/conpherence/conduit/ConpherenceUpdateThreadConduitAPIMethod.php index d5f3267a06..ebcf7f9a04 100644 --- a/src/applications/conpherence/conduit/ConpherenceUpdateThreadConduitAPIMethod.php +++ b/src/applications/conpherence/conduit/ConpherenceUpdateThreadConduitAPIMethod.php @@ -58,7 +58,7 @@ final class ConpherenceUpdateThreadConduitAPIMethod throw new ConduitException('ERR_USAGE_ROOM_NOT_FOUND'); } - $source = PhabricatorContentSource::newFromConduitRequest($request); + $source = $request->newContentSource(); $editor = id(new ConpherenceEditor()) ->setContentSource($source) ->setActor($user); diff --git a/src/applications/conpherence/mail/ConpherenceReplyHandler.php b/src/applications/conpherence/mail/ConpherenceReplyHandler.php index 7ec5d7f445..0a07cbad29 100644 --- a/src/applications/conpherence/mail/ConpherenceReplyHandler.php +++ b/src/applications/conpherence/mail/ConpherenceReplyHandler.php @@ -48,11 +48,7 @@ final class ConpherenceReplyHandler extends PhabricatorMailReplyHandler { $conpherence->attachParticipants($participants); } - $content_source = PhabricatorContentSource::newForSource( - PhabricatorContentSource::SOURCE_EMAIL, - array( - 'id' => $mail->getID(), - )); + $content_source = $mail->newContentSource(); $editor = id(new ConpherenceEditor()) ->setActor($user) diff --git a/src/applications/differential/conduit/DifferentialCloseConduitAPIMethod.php b/src/applications/differential/conduit/DifferentialCloseConduitAPIMethod.php index bd097c4b2f..e613647935 100644 --- a/src/applications/differential/conduit/DifferentialCloseConduitAPIMethod.php +++ b/src/applications/differential/conduit/DifferentialCloseConduitAPIMethod.php @@ -45,13 +45,11 @@ final class DifferentialCloseConduitAPIMethod ->setTransactionType(DifferentialTransaction::TYPE_ACTION) ->setNewValue(DifferentialAction::ACTION_CLOSE); - $content_source = PhabricatorContentSource::newForSource( - PhabricatorContentSource::SOURCE_CONDUIT, - array()); + $content_source = $request->newContentSource(); $editor = id(new DifferentialTransactionEditor()) ->setActor($viewer) - ->setContentSourceFromConduitRequest($request) + ->setContentSource($request->newContentSource()) ->setContinueOnMissingFields(true) ->setContinueOnNoEffect(true); diff --git a/src/applications/differential/conduit/DifferentialConduitAPIMethod.php b/src/applications/differential/conduit/DifferentialConduitAPIMethod.php index 1e5f03164c..e5b71c87bb 100644 --- a/src/applications/differential/conduit/DifferentialConduitAPIMethod.php +++ b/src/applications/differential/conduit/DifferentialConduitAPIMethod.php @@ -138,7 +138,7 @@ abstract class DifferentialConduitAPIMethod extends ConduitAPIMethod { $editor = id(new DifferentialTransactionEditor()) ->setActor($viewer) - ->setContentSourceFromConduitRequest($request) + ->setContentSource($request->newContentSource()) ->setContinueOnNoEffect(true) ->setContinueOnMissingFields(true); diff --git a/src/applications/differential/conduit/DifferentialCreateCommentConduitAPIMethod.php b/src/applications/differential/conduit/DifferentialCreateCommentConduitAPIMethod.php index c5d2bdb9dc..8f4b154876 100644 --- a/src/applications/differential/conduit/DifferentialCreateCommentConduitAPIMethod.php +++ b/src/applications/differential/conduit/DifferentialCreateCommentConduitAPIMethod.php @@ -77,7 +77,7 @@ final class DifferentialCreateCommentConduitAPIMethod $editor = id(new DifferentialTransactionEditor()) ->setActor($viewer) ->setDisableEmail($request->getValue('silent')) - ->setContentSourceFromConduitRequest($request) + ->setContentSource($request->newContentSource()) ->setContinueOnNoEffect(true) ->setContinueOnMissingFields(true); diff --git a/src/applications/differential/conduit/DifferentialCreateDiffConduitAPIMethod.php b/src/applications/differential/conduit/DifferentialCreateDiffConduitAPIMethod.php index 7a9ffdc6c1..8a0da78865 100644 --- a/src/applications/differential/conduit/DifferentialCreateDiffConduitAPIMethod.php +++ b/src/applications/differential/conduit/DifferentialCreateDiffConduitAPIMethod.php @@ -144,7 +144,7 @@ final class DifferentialCreateDiffConduitAPIMethod id(new DifferentialDiffEditor()) ->setActor($viewer) - ->setContentSourceFromConduitRequest($request) + ->setContentSource($request->newContentSource()) ->setContinueOnNoEffect(true) ->applyTransactions($diff, $xactions); diff --git a/src/applications/differential/conduit/DifferentialCreateRawDiffConduitAPIMethod.php b/src/applications/differential/conduit/DifferentialCreateRawDiffConduitAPIMethod.php index 75eb12b4f0..6f8c2e8640 100644 --- a/src/applications/differential/conduit/DifferentialCreateRawDiffConduitAPIMethod.php +++ b/src/applications/differential/conduit/DifferentialCreateRawDiffConduitAPIMethod.php @@ -85,7 +85,7 @@ final class DifferentialCreateRawDiffConduitAPIMethod id(new DifferentialDiffEditor()) ->setActor($viewer) - ->setContentSourceFromConduitRequest($request) + ->setContentSource($request->newContentSource()) ->setContinueOnNoEffect(true) ->setLookupRepository(false) // respect user choice ->applyTransactions($diff, $xactions); diff --git a/src/applications/differential/management/PhabricatorDifferentialAttachCommitWorkflow.php b/src/applications/differential/management/PhabricatorDifferentialAttachCommitWorkflow.php index 5150dba315..1ad102e03c 100644 --- a/src/applications/differential/management/PhabricatorDifferentialAttachCommitWorkflow.php +++ b/src/applications/differential/management/PhabricatorDifferentialAttachCommitWorkflow.php @@ -68,9 +68,7 @@ final class PhabricatorDifferentialAttachCommitWorkflow ->setViewer($viewer) ->setAuthorPHID($differential_phid); - $content_source = PhabricatorContentSource::newForSource( - PhabricatorContentSource::SOURCE_CONSOLE, - array()); + $content_source = $this->newContentSource(); $extraction_engine->updateRevisionWithCommit( $revision, diff --git a/src/applications/differential/storage/DifferentialInlineComment.php b/src/applications/differential/storage/DifferentialInlineComment.php index 7fe9299428..c27d59bbe3 100644 --- a/src/applications/differential/storage/DifferentialInlineComment.php +++ b/src/applications/differential/storage/DifferentialInlineComment.php @@ -18,8 +18,7 @@ final class DifferentialInlineComment public function getTransactionCommentForSave() { $content_source = PhabricatorContentSource::newForSource( - PhabricatorContentSource::SOURCE_LEGACY, - array()); + PhabricatorOldWorldContentSource::SOURCECONST); $this->proxy ->setViewPolicy('public') diff --git a/src/applications/diffusion/conduit/DiffusionCreateCommentConduitAPIMethod.php b/src/applications/diffusion/conduit/DiffusionCreateCommentConduitAPIMethod.php index 5543b759d0..51a494425f 100644 --- a/src/applications/diffusion/conduit/DiffusionCreateCommentConduitAPIMethod.php +++ b/src/applications/diffusion/conduit/DiffusionCreateCommentConduitAPIMethod.php @@ -95,7 +95,7 @@ final class DiffusionCreateCommentConduitAPIMethod id(new PhabricatorAuditEditor()) ->setActor($request->getUser()) - ->setContentSourceFromConduitRequest($request) + ->setContentSource($request->newContentSource()) ->setDisableEmail($request->getValue('silent')) ->setContinueOnMissingFields(true) ->applyTransactions($commit, $xactions); diff --git a/src/applications/harbormaster/engine/HarbormasterBuildEngine.php b/src/applications/harbormaster/engine/HarbormasterBuildEngine.php index 5eabd85034..75a078a9d7 100644 --- a/src/applications/harbormaster/engine/HarbormasterBuildEngine.php +++ b/src/applications/harbormaster/engine/HarbormasterBuildEngine.php @@ -458,8 +458,7 @@ final class HarbormasterBuildEngine extends Phobject { ->getPHID(); $daemon_source = PhabricatorContentSource::newForSource( - PhabricatorContentSource::SOURCE_DAEMON, - array()); + PhabricatorDaemonContentSource::SOURCECONST); $editor = $object->getApplicationTransactionEditor() ->setActor($viewer) diff --git a/src/applications/herald/contentsource/PhabricatorHeraldContentSource.php b/src/applications/herald/contentsource/PhabricatorHeraldContentSource.php new file mode 100644 index 0000000000..ad4adfce55 --- /dev/null +++ b/src/applications/herald/contentsource/PhabricatorHeraldContentSource.php @@ -0,0 +1,16 @@ +setKey(self::FIELDCONST) - ->setDefault(PhabricatorContentSource::SOURCE_WEB) + ->setDefault(PhabricatorWebContentSource::SOURCECONST) ->setOptions($map); } diff --git a/src/applications/lipsum/generator/PhabricatorTestDataGenerator.php b/src/applications/lipsum/generator/PhabricatorTestDataGenerator.php index aacef542b1..b44895ae87 100644 --- a/src/applications/lipsum/generator/PhabricatorTestDataGenerator.php +++ b/src/applications/lipsum/generator/PhabricatorTestDataGenerator.php @@ -56,8 +56,7 @@ abstract class PhabricatorTestDataGenerator extends Phobject { protected function getLipsumContentSource() { return PhabricatorContentSource::newForSource( - PhabricatorContentSource::SOURCE_LIPSUM, - array()); + PhabricatorLipsumContentSource::SOURCECONST); } /** diff --git a/src/applications/maniphest/__tests__/ManiphestTaskTestCase.php b/src/applications/maniphest/__tests__/ManiphestTaskTestCase.php index 18f433fe52..cf1da51bca 100644 --- a/src/applications/maniphest/__tests__/ManiphestTaskTestCase.php +++ b/src/applications/maniphest/__tests__/ManiphestTaskTestCase.php @@ -207,7 +207,7 @@ final class ManiphestTaskTestCase extends PhabricatorTestCase { ManiphestTask $task, array $xactions) { - $content_source = PhabricatorContentSource::newConsoleSource(); + $content_source = $this->newContentSource(); $editor = id(new ManiphestTransactionEditor()) ->setActor($viewer) diff --git a/src/applications/maniphest/conduit/ManiphestConduitAPIMethod.php b/src/applications/maniphest/conduit/ManiphestConduitAPIMethod.php index e72ffa4d46..d2a8de7d81 100644 --- a/src/applications/maniphest/conduit/ManiphestConduitAPIMethod.php +++ b/src/applications/maniphest/conduit/ManiphestConduitAPIMethod.php @@ -192,9 +192,7 @@ abstract class ManiphestConduitAPIMethod extends ConduitAPIMethod { return; } - $content_source = PhabricatorContentSource::newForSource( - PhabricatorContentSource::SOURCE_CONDUIT, - array()); + $content_source = $request->newContentSource(); $editor = id(new ManiphestTransactionEditor()) ->setActor($request->getUser()) diff --git a/src/applications/maniphest/lipsum/PhabricatorManiphestTaskTestDataGenerator.php b/src/applications/maniphest/lipsum/PhabricatorManiphestTaskTestDataGenerator.php index e4147ad223..5b52aaa480 100644 --- a/src/applications/maniphest/lipsum/PhabricatorManiphestTaskTestDataGenerator.php +++ b/src/applications/maniphest/lipsum/PhabricatorManiphestTaskTestDataGenerator.php @@ -15,9 +15,7 @@ final class PhabricatorManiphestTaskTestDataGenerator ->setSubPriority($this->generateTaskSubPriority()) ->setTitle($this->generateTitle()); - $content_source = PhabricatorContentSource::newForSource( - PhabricatorContentSource::SOURCE_UNKNOWN, - array()); + $content_source = $this->getLipsumContentSource(); $template = new ManiphestTransaction(); // Accumulate Transactions diff --git a/src/applications/metamta/contentsource/PhabricatorContentSource.php b/src/applications/metamta/contentsource/PhabricatorContentSource.php deleted file mode 100644 index e2320eb85f..0000000000 --- a/src/applications/metamta/contentsource/PhabricatorContentSource.php +++ /dev/null @@ -1,104 +0,0 @@ - - } - - public static function newForSource($source, array $params) { - $obj = new PhabricatorContentSource(); - $obj->source = $source; - $obj->params = $params; - - return $obj; - } - - public static function newFromSerialized($serialized) { - $dict = json_decode($serialized, true); - if (!is_array($dict)) { - $dict = array(); - } - - $obj = new PhabricatorContentSource(); - $obj->source = idx($dict, 'source', self::SOURCE_UNKNOWN); - $obj->params = idx($dict, 'params', array()); - - return $obj; - } - - public static function newConsoleSource() { - return self::newForSource( - self::SOURCE_CONSOLE, - array()); - } - - public static function newFromRequest(AphrontRequest $request) { - return self::newForSource( - self::SOURCE_WEB, - array()); - } - - public static function newFromConduitRequest(ConduitAPIRequest $request) { - return self::newForSource( - self::SOURCE_CONDUIT, - array()); - } - - public static function getSourceNameMap() { - return array( - self::SOURCE_WEB => pht('Web'), - self::SOURCE_EMAIL => pht('Email'), - self::SOURCE_CONDUIT => pht('Conduit'), - self::SOURCE_MOBILE => pht('Mobile'), - self::SOURCE_TABLET => pht('Tablet'), - self::SOURCE_FAX => pht('Fax'), - self::SOURCE_CONSOLE => pht('Console'), - self::SOURCE_LEGACY => pht('Legacy'), - self::SOURCE_HERALD => pht('Herald'), - self::SOURCE_DAEMON => pht('Daemons'), - self::SOURCE_LIPSUM => pht('Lipsum'), - self::SOURCE_UNKNOWN => pht('Old World'), - self::SOURCE_PHORTUNE => pht('Phortune'), - self::SOURCE_BULK => pht('Bulk Edit'), - ); - } - - public function serialize() { - return json_encode(array( - 'source' => $this->getSource(), - 'params' => $this->getParams(), - )); - } - - public function getSource() { - return $this->source; - } - - public function getParams() { - return $this->params; - } - - public function getParam($key, $default = null) { - return idx($this->params, $key, $default); - } - -} diff --git a/src/applications/metamta/contentsource/PhabricatorEmailContentSource.php b/src/applications/metamta/contentsource/PhabricatorEmailContentSource.php new file mode 100644 index 0000000000..78a66b4150 --- /dev/null +++ b/src/applications/metamta/contentsource/PhabricatorEmailContentSource.php @@ -0,0 +1,16 @@ +saveAndSend(); } + public function newContentSource() { + return PhabricatorContentSource::newForSource( + PhabricatorEmailContentSource::SOURCECONST, + array( + 'id' => $this->getID(), + )); + } + } diff --git a/src/applications/nuance/item/NuanceGitHubEventItemType.php b/src/applications/nuance/item/NuanceGitHubEventItemType.php index 2bccfb76b4..75f44e8964 100644 --- a/src/applications/nuance/item/NuanceGitHubEventItemType.php +++ b/src/applications/nuance/item/NuanceGitHubEventItemType.php @@ -323,10 +323,9 @@ final class NuanceGitHubEventItemType // TODO: Preserve the item's original source. $source = PhabricatorContentSource::newForSource( - PhabricatorContentSource::SOURCE_DAEMON, - array()); + PhabricatorDaemonContentSource::SOURCECONST); - // TOOD: This should really be the external source. + // TODO: This should really be the external source. $acting_phid = $nuance_phid; $editor = id(new ManiphestTransactionEditor()) diff --git a/src/applications/nuance/item/NuanceItemType.php b/src/applications/nuance/item/NuanceItemType.php index e8397b13f8..d4187bf418 100644 --- a/src/applications/nuance/item/NuanceItemType.php +++ b/src/applications/nuance/item/NuanceItemType.php @@ -119,8 +119,7 @@ abstract class NuanceItemType // TODO: Maybe preserve the actor's original content source? $source = PhabricatorContentSource::newForSource( - PhabricatorContentSource::SOURCE_DAEMON, - array()); + PhabricatorDaemonContentSource::SOURCECONST); $editor = id(new NuanceItemEditor()) ->setActor($viewer) diff --git a/src/applications/paste/conduit/PasteCreateConduitAPIMethod.php b/src/applications/paste/conduit/PasteCreateConduitAPIMethod.php index 2dae0132d4..5cdf6afdab 100644 --- a/src/applications/paste/conduit/PasteCreateConduitAPIMethod.php +++ b/src/applications/paste/conduit/PasteCreateConduitAPIMethod.php @@ -61,7 +61,7 @@ final class PasteCreateConduitAPIMethod extends PasteConduitAPIMethod { $editor = id(new PhabricatorPasteEditor()) ->setActor($viewer) ->setContinueOnNoEffect(true) - ->setContentSourceFromConduitRequest($request); + ->setContentSource($request->newContentSource()); $xactions = $editor->applyTransactions($paste, $xactions); diff --git a/src/applications/paste/mail/PasteCreateMailReceiver.php b/src/applications/paste/mail/PasteCreateMailReceiver.php index 672667cd65..85acf7f45d 100644 --- a/src/applications/paste/mail/PasteCreateMailReceiver.php +++ b/src/applications/paste/mail/PasteCreateMailReceiver.php @@ -37,11 +37,7 @@ final class PasteCreateMailReceiver extends PhabricatorMailReceiver { $paste = PhabricatorPaste::initializeNewPaste($sender); - $content_source = PhabricatorContentSource::newForSource( - PhabricatorContentSource::SOURCE_EMAIL, - array( - 'id' => $mail->getID(), - )); + $content_source = $mail->newContentSource(); $editor = id(new PhabricatorPasteEditor()) ->setActor($sender) @@ -69,4 +65,5 @@ final class PasteCreateMailReceiver extends PhabricatorMailReceiver { ->saveAndSend(); } + } diff --git a/src/applications/pholio/lipsum/PhabricatorPholioMockTestDataGenerator.php b/src/applications/pholio/lipsum/PhabricatorPholioMockTestDataGenerator.php index ce620a0d3a..ac61327b39 100644 --- a/src/applications/pholio/lipsum/PhabricatorPholioMockTestDataGenerator.php +++ b/src/applications/pholio/lipsum/PhabricatorPholioMockTestDataGenerator.php @@ -13,9 +13,8 @@ final class PhabricatorPholioMockTestDataGenerator ->loadOneWhere('phid = %s', $author_phid); $mock = PholioMock::initializeNewMock($author); - $content_source = PhabricatorContentSource::newForSource( - PhabricatorContentSource::SOURCE_UNKNOWN, - array()); + $content_source = $this->getLipsumContentSource(); + $template = id(new PholioTransaction()) ->setContentSource($content_source); diff --git a/src/applications/phortune/contentsource/PhabricatorPhortuneContentSource.php b/src/applications/phortune/contentsource/PhabricatorPhortuneContentSource.php new file mode 100644 index 0000000000..f2f3247376 --- /dev/null +++ b/src/applications/phortune/contentsource/PhabricatorPhortuneContentSource.php @@ -0,0 +1,16 @@ +setNewValue(true); $content_source = PhabricatorContentSource::newForSource( - PhabricatorContentSource::SOURCE_PHORTUNE, - array()); + PhabricatorPhortuneContentSource::SOURCECONST); $editor = id(new PhortuneCartEditor()) ->setActor($omnipotent_user) diff --git a/src/applications/phortune/worker/PhortuneSubscriptionWorker.php b/src/applications/phortune/worker/PhortuneSubscriptionWorker.php index 96f1948528..19399150e8 100644 --- a/src/applications/phortune/worker/PhortuneSubscriptionWorker.php +++ b/src/applications/phortune/worker/PhortuneSubscriptionWorker.php @@ -96,8 +96,7 @@ final class PhortuneSubscriptionWorker extends PhabricatorWorker { ->setNewValue(true); $content_source = PhabricatorContentSource::newForSource( - PhabricatorContentSource::SOURCE_PHORTUNE, - array()); + PhabricatorPhortuneContentSource::SOURCECONST); $acting_phid = id(new PhabricatorPhortuneApplication())->getPHID(); $editor = id(new PhortuneCartEditor()) diff --git a/src/applications/phriction/conduit/PhrictionCreateConduitAPIMethod.php b/src/applications/phriction/conduit/PhrictionCreateConduitAPIMethod.php index e3d28941bb..36c74f4a68 100644 --- a/src/applications/phriction/conduit/PhrictionCreateConduitAPIMethod.php +++ b/src/applications/phriction/conduit/PhrictionCreateConduitAPIMethod.php @@ -55,7 +55,7 @@ final class PhrictionCreateConduitAPIMethod extends PhrictionConduitAPIMethod { $editor = id(new PhrictionTransactionEditor()) ->setActor($request->getUser()) - ->setContentSourceFromConduitRequest($request) + ->setContentSource($request->newContentSource()) ->setContinueOnNoEffect(true) ->setDescription($request->getValue('description')); diff --git a/src/applications/phriction/conduit/PhrictionEditConduitAPIMethod.php b/src/applications/phriction/conduit/PhrictionEditConduitAPIMethod.php index f9c8c26a3e..e99a866529 100644 --- a/src/applications/phriction/conduit/PhrictionEditConduitAPIMethod.php +++ b/src/applications/phriction/conduit/PhrictionEditConduitAPIMethod.php @@ -50,7 +50,7 @@ final class PhrictionEditConduitAPIMethod extends PhrictionConduitAPIMethod { $editor = id(new PhrictionTransactionEditor()) ->setActor($request->getUser()) - ->setContentSourceFromConduitRequest($request) + ->setContentSource($request->newContentSource()) ->setContinueOnNoEffect(true) ->setDescription($request->getValue('description')); diff --git a/src/applications/project/__tests__/PhabricatorProjectCoreTestCase.php b/src/applications/project/__tests__/PhabricatorProjectCoreTestCase.php index 39efcadb55..e2b2f9688d 100644 --- a/src/applications/project/__tests__/PhabricatorProjectCoreTestCase.php +++ b/src/applications/project/__tests__/PhabricatorProjectCoreTestCase.php @@ -1087,7 +1087,7 @@ final class PhabricatorProjectCoreTestCase extends PhabricatorTestCase { $editor = id(new ManiphestTransactionEditor()) ->setActor($viewer) - ->setContentSource(PhabricatorContentSource::newConsoleSource()) + ->setContentSource($this->newContentSource()) ->setContinueOnNoEffect(true) ->applyTransactions($task, $xactions); } @@ -1203,7 +1203,7 @@ final class PhabricatorProjectCoreTestCase extends PhabricatorTestCase { $editor = id(new ManiphestTransactionEditor()) ->setActor($viewer) - ->setContentSource(PhabricatorContentSource::newConsoleSource()) + ->setContentSource($this->newContentSource()) ->setContinueOnNoEffect(true) ->applyTransactions($task, $xactions); } @@ -1239,7 +1239,7 @@ final class PhabricatorProjectCoreTestCase extends PhabricatorTestCase { $editor = id(new ManiphestTransactionEditor()) ->setActor($viewer) - ->setContentSource(PhabricatorContentSource::newConsoleSource()) + ->setContentSource($this->newContentSource()) ->setContinueOnNoEffect(true) ->applyTransactions($task, $xactions); @@ -1464,7 +1464,7 @@ final class PhabricatorProjectCoreTestCase extends PhabricatorTestCase { $editor = id(new PhabricatorProjectTransactionEditor()) ->setActor($user) - ->setContentSource(PhabricatorContentSource::newConsoleSource()) + ->setContentSource($this->newContentSource()) ->setContinueOnNoEffect(true) ->applyTransactions($project, $xactions); } diff --git a/src/applications/project/conduit/ProjectCreateConduitAPIMethod.php b/src/applications/project/conduit/ProjectCreateConduitAPIMethod.php index a209fd9a40..aefade63a2 100644 --- a/src/applications/project/conduit/ProjectCreateConduitAPIMethod.php +++ b/src/applications/project/conduit/ProjectCreateConduitAPIMethod.php @@ -71,7 +71,7 @@ final class ProjectCreateConduitAPIMethod extends ProjectConduitAPIMethod { $editor = id(new PhabricatorProjectTransactionEditor()) ->setActor($user) ->setContinueOnNoEffect(true) - ->setContentSourceFromConduitRequest($request); + ->setContentSource($request->newContentSource()); $editor->applyTransactions($project, $xactions); diff --git a/src/applications/releeph/conduit/ReleephRequestConduitAPIMethod.php b/src/applications/releeph/conduit/ReleephRequestConduitAPIMethod.php index 8473c0c7b5..0ac3caf15e 100644 --- a/src/applications/releeph/conduit/ReleephRequestConduitAPIMethod.php +++ b/src/applications/releeph/conduit/ReleephRequestConduitAPIMethod.php @@ -144,10 +144,7 @@ final class ReleephRequestConduitAPIMethod extends ReleephConduitAPIMethod { $editor = id(new ReleephRequestTransactionalEditor()) ->setActor($user) ->setContinueOnNoEffect(true) - ->setContentSource( - PhabricatorContentSource::newForSource( - PhabricatorContentSource::SOURCE_CONDUIT, - array())); + ->setContentSource($request->newContentSource()); $editor->applyTransactions($releeph_request, $xactions); } diff --git a/src/applications/releeph/conduit/work/ReleephWorkRecordConduitAPIMethod.php b/src/applications/releeph/conduit/work/ReleephWorkRecordConduitAPIMethod.php index d32249fe65..9cfbe72c99 100644 --- a/src/applications/releeph/conduit/work/ReleephWorkRecordConduitAPIMethod.php +++ b/src/applications/releeph/conduit/work/ReleephWorkRecordConduitAPIMethod.php @@ -65,10 +65,7 @@ final class ReleephWorkRecordConduitAPIMethod $editor = id(new ReleephRequestTransactionalEditor()) ->setActor($request->getUser()) ->setContinueOnNoEffect(true) - ->setContentSource( - PhabricatorContentSource::newForSource( - PhabricatorContentSource::SOURCE_CONDUIT, - array())); + ->setContentSource($request->newContentSource()); $editor->applyTransactions($releeph_request, $xactions); } diff --git a/src/applications/releeph/conduit/work/ReleephWorkRecordPickStatusConduitAPIMethod.php b/src/applications/releeph/conduit/work/ReleephWorkRecordPickStatusConduitAPIMethod.php index ead3d9dd2a..5de0108a25 100644 --- a/src/applications/releeph/conduit/work/ReleephWorkRecordPickStatusConduitAPIMethod.php +++ b/src/applications/releeph/conduit/work/ReleephWorkRecordPickStatusConduitAPIMethod.php @@ -64,10 +64,7 @@ final class ReleephWorkRecordPickStatusConduitAPIMethod $editor = id(new ReleephRequestTransactionalEditor()) ->setActor($request->getUser()) ->setContinueOnNoEffect(true) - ->setContentSource( - PhabricatorContentSource::newForSource( - PhabricatorContentSource::SOURCE_CONDUIT, - array())); + ->setContentSource($request->newContentSource()); $xactions = array(); diff --git a/src/applications/releeph/differential/DifferentialReleephRequestFieldSpecification.php b/src/applications/releeph/differential/DifferentialReleephRequestFieldSpecification.php index 26e708a00c..bdb63e6c9c 100644 --- a/src/applications/releeph/differential/DifferentialReleephRequestFieldSpecification.php +++ b/src/applications/releeph/differential/DifferentialReleephRequestFieldSpecification.php @@ -301,8 +301,7 @@ final class DifferentialReleephRequestFieldSpecification extends Phobject { ->setContinueOnNoEffect(true) ->setContentSource( PhabricatorContentSource::newForSource( - PhabricatorContentSource::SOURCE_UNKNOWN, - array())); + PhabricatorUnknownContentSource::SOURCECONST)); $editor->applyTransactions($releeph_request, $xactions); } diff --git a/src/applications/repository/management/PhabricatorRepositoryManagementEditWorkflow.php b/src/applications/repository/management/PhabricatorRepositoryManagementEditWorkflow.php index 83447fcc18..cc33f1021c 100644 --- a/src/applications/repository/management/PhabricatorRepositoryManagementEditWorkflow.php +++ b/src/applications/repository/management/PhabricatorRepositoryManagementEditWorkflow.php @@ -117,7 +117,7 @@ final class PhabricatorRepositoryManagementEditWorkflow pht('Specify one or more fields to edit!')); } - $content_source = PhabricatorContentSource::newConsoleSource(); + $content_source = $this->newContentSource(); $editor = id(new PhabricatorRepositoryEditor()) ->setActor($actor) diff --git a/src/applications/repository/worker/PhabricatorRepositoryCommitHeraldWorker.php b/src/applications/repository/worker/PhabricatorRepositoryCommitHeraldWorker.php index 0aa4dad187..9ad8ef2b66 100644 --- a/src/applications/repository/worker/PhabricatorRepositoryCommitHeraldWorker.php +++ b/src/applications/repository/worker/PhabricatorRepositoryCommitHeraldWorker.php @@ -30,9 +30,7 @@ final class PhabricatorRepositoryCommitHeraldWorker $commit->attachRepository($repository); - $content_source = PhabricatorContentSource::newForSource( - PhabricatorContentSource::SOURCE_DAEMON, - array()); + $content_source = $this->newContentSource(); $committer_phid = $data->getCommitDetail('committerPHID'); $author_phid = $data->getCommitDetail('authorPHID'); diff --git a/src/applications/repository/worker/commitmessageparser/PhabricatorRepositoryCommitMessageParserWorker.php b/src/applications/repository/worker/commitmessageparser/PhabricatorRepositoryCommitMessageParserWorker.php index dbb912eda4..25eedf0be2 100644 --- a/src/applications/repository/worker/commitmessageparser/PhabricatorRepositoryCommitMessageParserWorker.php +++ b/src/applications/repository/worker/commitmessageparser/PhabricatorRepositoryCommitMessageParserWorker.php @@ -221,9 +221,7 @@ abstract class PhabricatorRepositoryCommitMessageParserWorker ->setViewer($actor) ->setAuthorPHID($acting_as_phid); - $content_source = PhabricatorContentSource::newForSource( - PhabricatorContentSource::SOURCE_DAEMON, - array()); + $content_source = $this->newContentSource(); $update_data = $extraction_engine->updateRevisionWithCommit( $revision, @@ -337,9 +335,7 @@ abstract class PhabricatorRepositoryCommitMessageParserWorker $xactions[] = $edge_xaction; - $content_source = PhabricatorContentSource::newForSource( - PhabricatorContentSource::SOURCE_DAEMON, - array()); + $content_source = $this->newContentSource(); $editor = id(new ManiphestTransactionEditor()) ->setActor($actor) diff --git a/src/applications/spaces/__tests__/PhabricatorSpacesTestCase.php b/src/applications/spaces/__tests__/PhabricatorSpacesTestCase.php index f17d0f404a..4215ec96fe 100644 --- a/src/applications/spaces/__tests__/PhabricatorSpacesTestCase.php +++ b/src/applications/spaces/__tests__/PhabricatorSpacesTestCase.php @@ -215,7 +215,7 @@ final class PhabricatorSpacesTestCase extends PhabricatorTestCase { ->setNewValue($is_default); } - $content_source = PhabricatorContentSource::newConsoleSource(); + $content_source = $this->newContentSource(); $editor = id(new PhabricatorSpacesNamespaceEditor()) ->setActor($actor) diff --git a/src/applications/tokens/conduit/TokenGiveConduitAPIMethod.php b/src/applications/tokens/conduit/TokenGiveConduitAPIMethod.php index 4e0a463a74..eb591025b2 100644 --- a/src/applications/tokens/conduit/TokenGiveConduitAPIMethod.php +++ b/src/applications/tokens/conduit/TokenGiveConduitAPIMethod.php @@ -22,7 +22,7 @@ final class TokenGiveConduitAPIMethod extends TokenConduitAPIMethod { } protected function execute(ConduitAPIRequest $request) { - $content_source = PhabricatorContentSource::newFromConduitRequest($request); + $content_source = $request->newContentSource(); $editor = id(new PhabricatorTokenGivenEditor()) ->setActor($request->getUser()) diff --git a/src/applications/transactions/controller/PhabricatorApplicationTransactionCommentRawController.php b/src/applications/transactions/controller/PhabricatorApplicationTransactionCommentRawController.php index 65b6282aa9..ae3fb7520c 100644 --- a/src/applications/transactions/controller/PhabricatorApplicationTransactionCommentRawController.php +++ b/src/applications/transactions/controller/PhabricatorApplicationTransactionCommentRawController.php @@ -37,9 +37,9 @@ final class PhabricatorApplicationTransactionCommentRawController $addendum = null; if ($request->getExists('email')) { $content_source = $xaction->getContentSource(); - $source_email = PhabricatorContentSource::SOURCE_EMAIL; + $source_email = PhabricatorEmailContentSource::SOURCECONST; if ($content_source->getSource() == $source_email) { - $source_id = $content_source->getParam('id'); + $source_id = $content_source->getContentSourceParameter('id'); if ($source_id) { $message = id(new PhabricatorMetaMTAReceivedMail())->loadOneWhere( 'id = %d', diff --git a/src/applications/transactions/editengine/PhabricatorEditEngine.php b/src/applications/transactions/editengine/PhabricatorEditEngine.php index 8be7c9d6f2..3e6ff9c872 100644 --- a/src/applications/transactions/editengine/PhabricatorEditEngine.php +++ b/src/applications/transactions/editengine/PhabricatorEditEngine.php @@ -1684,7 +1684,7 @@ abstract class PhabricatorEditEngine $editor = $object->getApplicationTransactionEditor() ->setActor($viewer) - ->setContentSourceFromConduitRequest($request) + ->setContentSource($request->newContentSource()) ->setContinueOnNoEffect(true); if (!$this->getIsCreate()) { diff --git a/src/applications/transactions/editor/PhabricatorApplicationTransactionEditor.php b/src/applications/transactions/editor/PhabricatorApplicationTransactionEditor.php index cbfaebb182..d7c0bbf5f6 100644 --- a/src/applications/transactions/editor/PhabricatorApplicationTransactionEditor.php +++ b/src/applications/transactions/editor/PhabricatorApplicationTransactionEditor.php @@ -733,16 +733,6 @@ abstract class PhabricatorApplicationTransactionEditor PhabricatorContentSource::newFromRequest($request)); } - public function setContentSourceFromConduitRequest( - ConduitAPIRequest $request) { - - $content_source = PhabricatorContentSource::newForSource( - PhabricatorContentSource::SOURCE_CONDUIT, - array()); - - return $this->setContentSource($content_source); - } - public function getContentSource() { return $this->contentSource; } @@ -979,8 +969,7 @@ abstract class PhabricatorApplicationTransactionEditor // out from transcripts, but it would be cleaner if you didn't have to. $herald_source = PhabricatorContentSource::newForSource( - PhabricatorContentSource::SOURCE_HERALD, - array()); + PhabricatorHeraldContentSource::SOURCECONST); $herald_editor = newv(get_class($this), array()) ->setContinueOnNoEffect(true) diff --git a/src/applications/transactions/replyhandler/PhabricatorApplicationTransactionReplyHandler.php b/src/applications/transactions/replyhandler/PhabricatorApplicationTransactionReplyHandler.php index 560a750f00..5457708953 100644 --- a/src/applications/transactions/replyhandler/PhabricatorApplicationTransactionReplyHandler.php +++ b/src/applications/transactions/replyhandler/PhabricatorApplicationTransactionReplyHandler.php @@ -18,11 +18,7 @@ abstract class PhabricatorApplicationTransactionReplyHandler } private function newEditor(PhabricatorMetaMTAReceivedMail $mail) { - $content_source = PhabricatorContentSource::newForSource( - PhabricatorContentSource::SOURCE_EMAIL, - array( - 'id' => $mail->getID(), - )); + $content_source = $mail->newContentSource(); $editor = $this->getMailReceiver() ->getApplicationTransactionEditor() diff --git a/src/applications/transactions/worker/PhabricatorApplicationTransactionPublishWorker.php b/src/applications/transactions/worker/PhabricatorApplicationTransactionPublishWorker.php index 1b017c224e..0369fbff54 100644 --- a/src/applications/transactions/worker/PhabricatorApplicationTransactionPublishWorker.php +++ b/src/applications/transactions/worker/PhabricatorApplicationTransactionPublishWorker.php @@ -62,9 +62,7 @@ final class PhabricatorApplicationTransactionPublishWorker PhabricatorApplicationTransactionInterface $object) { $data = $this->getTaskData(); - $daemon_source = PhabricatorContentSource::newForSource( - PhabricatorContentSource::SOURCE_DAEMON, - array()); + $daemon_source = $this->newContentSource(); $viewer = PhabricatorUser::getOmnipotentUser(); $editor = $object->getApplicationTransactionEditor() diff --git a/src/infrastructure/contentsource/PhabricatorConduitContentSource.php b/src/infrastructure/contentsource/PhabricatorConduitContentSource.php new file mode 100644 index 0000000000..64820a236c --- /dev/null +++ b/src/infrastructure/contentsource/PhabricatorConduitContentSource.php @@ -0,0 +1,16 @@ +getPhobjectClassConstant('SOURCECONST', 32); + } + + final public static function getAllContentSources() { + return id(new PhutilClassMapQuery()) + ->setAncestorClass(__CLASS__) + ->setUniqueMethod('getSourceTypeConstant') + ->execute(); + } + + /** + * Construct a new content source object. + * + * @param const The source type constant to build a source for. + * @param array Source parameters. + * @param bool True to suppress errors and force construction of a source + * even if the source type is not valid. + * @return PhabricatorContentSource New source object. + */ + final public static function newForSource( + $source, + array $params = array(), + $force = false) { + + $map = self::getAllContentSources(); + if (isset($map[$source])) { + $obj = clone $map[$source]; + } else { + if ($force) { + $obj = new PhabricatorUnknownContentSource(); + } else { + throw new Exception( + pht( + 'Content source type "%s" is not known to Phabricator!', + $source)); + } + } + + $obj->source = $source; + $obj->params = $params; + + return $obj; + } + + public static function newFromSerialized($serialized) { + $dict = json_decode($serialized, true); + if (!is_array($dict)) { + $dict = array(); + } + + $source = idx($dict, 'source'); + $params = idx($dict, 'params'); + if (!is_array($params)) { + $params = array(); + } + + return self::newForSource($source, $params, true); + } + + public static function newFromRequest(AphrontRequest $request) { + return self::newForSource( + PhabricatorWebContentSource::SOURCECONST); + } + + final public function serialize() { + return phutil_json_encode( + array( + 'source' => $this->getSource(), + 'params' => $this->params, + )); + } + + final public function getSource() { + return $this->source; + } + + final public function getContentSourceParameter($key, $default = null) { + return idx($this->params, $key, $default); + } + +} diff --git a/src/infrastructure/contentsource/PhabricatorContentSourceModule.php b/src/infrastructure/contentsource/PhabricatorContentSourceModule.php new file mode 100644 index 0000000000..c9bd3347f3 --- /dev/null +++ b/src/infrastructure/contentsource/PhabricatorContentSourceModule.php @@ -0,0 +1,51 @@ +getViewer(); + + $sources = PhabricatorContentSource::getAllContentSources(); + ksort($sources); + + $rows = array(); + foreach ($sources as $source) { + $rows[] = array( + $source->getSourceTypeConstant(), + get_class($source), + $source->getSourceName(), + $source->getSourceDescription(), + ); + } + + $table = id(new AphrontTableView($rows)) + ->setHeaders( + array( + pht('Key'), + pht('Class'), + pht('Source'), + pht('Description'), + )) + ->setColumnClasses( + array( + null, + null, + 'pri', + 'wide', + )); + + return id(new PHUIObjectBoxView()) + ->setHeaderText(pht('Content Sources')) + ->setTable($table); + } + +} diff --git a/src/applications/metamta/contentsource/PhabricatorContentSourceView.php b/src/infrastructure/contentsource/PhabricatorContentSourceView.php similarity index 61% rename from src/applications/metamta/contentsource/PhabricatorContentSourceView.php rename to src/infrastructure/contentsource/PhabricatorContentSourceView.php index 5b19f41cb2..14bacb08d9 100644 --- a/src/applications/metamta/contentsource/PhabricatorContentSourceView.php +++ b/src/infrastructure/contentsource/PhabricatorContentSourceView.php @@ -10,21 +10,14 @@ final class PhabricatorContentSourceView extends AphrontView { } public function getSourceName() { - $map = PhabricatorContentSource::getSourceNameMap(); - $source = $this->contentSource->getSource(); - return idx($map, $source, null); - + return $this->contentSource->getSourceName(); } public function render() { require_celerity_resource('phabricator-content-source-view-css'); - $map = PhabricatorContentSource::getSourceNameMap(); - - $source = $this->contentSource->getSource(); - $type = idx($map, $source, null); - - if (!$type) { + $name = $this->getSourceName(); + if ($name === null) { return null; } @@ -33,7 +26,7 @@ final class PhabricatorContentSourceView extends AphrontView { array( 'class' => 'phabricator-content-source-view', ), - pht('Via %s', $type)); + pht('Via %s', $name)); } } diff --git a/src/infrastructure/contentsource/PhabricatorFaxContentSource.php b/src/infrastructure/contentsource/PhabricatorFaxContentSource.php new file mode 100644 index 0000000000..36da91365b --- /dev/null +++ b/src/infrastructure/contentsource/PhabricatorFaxContentSource.php @@ -0,0 +1,16 @@ +getSource(); + if (strlen($source)) { + return pht('Unknown ("%s")', $source); + } else { + return pht('Unknown'); + } + } + + public function getSourceDescription() { + return pht('Content with no known source.'); + } + +} diff --git a/src/infrastructure/contentsource/PhabricatorWebContentSource.php b/src/infrastructure/contentsource/PhabricatorWebContentSource.php new file mode 100644 index 0000000000..d788148e52 --- /dev/null +++ b/src/infrastructure/contentsource/PhabricatorWebContentSource.php @@ -0,0 +1,16 @@ +setTransactionType($type_status) ->setNewValue($status); - $daemon_source = PhabricatorContentSource::newForSource( - PhabricatorContentSource::SOURCE_DAEMON, - array()); + $daemon_source = $this->newContentSource(); $app_phid = id(new PhabricatorDaemonsApplication())->getPHID(); diff --git a/src/infrastructure/daemon/workers/storage/PhabricatorWorkerBulkJob.php b/src/infrastructure/daemon/workers/storage/PhabricatorWorkerBulkJob.php index ca7508d2b2..feb25a0128 100644 --- a/src/infrastructure/daemon/workers/storage/PhabricatorWorkerBulkJob.php +++ b/src/infrastructure/daemon/workers/storage/PhabricatorWorkerBulkJob.php @@ -102,7 +102,7 @@ final class PhabricatorWorkerBulkJob public function newContentSource() { return PhabricatorContentSource::newForSource( - PhabricatorContentSource::SOURCE_BULK, + PhabricatorBulkContentSource::SOURCECONST, array( 'jobID' => $this->getID(), )); diff --git a/src/infrastructure/management/PhabricatorManagementWorkflow.php b/src/infrastructure/management/PhabricatorManagementWorkflow.php index a2305b8ff0..0cd8c0230e 100644 --- a/src/infrastructure/management/PhabricatorManagementWorkflow.php +++ b/src/infrastructure/management/PhabricatorManagementWorkflow.php @@ -26,4 +26,9 @@ abstract class PhabricatorManagementWorkflow extends PhutilArgumentWorkflow { return $epoch; } + protected function newContentSource() { + return PhabricatorContentSource::newForSource( + PhabricatorConsoleContentSource::SOURCECONST); + } + } diff --git a/src/infrastructure/testing/PhabricatorTestCase.php b/src/infrastructure/testing/PhabricatorTestCase.php index 068c2ed557..c9a6ba986c 100644 --- a/src/infrastructure/testing/PhabricatorTestCase.php +++ b/src/infrastructure/testing/PhabricatorTestCase.php @@ -229,5 +229,9 @@ abstract class PhabricatorTestCase extends PhutilTestCase { } } + protected function newContentSource() { + return PhabricatorContentSource::newForSource( + PhabricatorUnitTestContentSource::SOURCECONST); + } } diff --git a/src/view/phui/PHUITimelineEventView.php b/src/view/phui/PHUITimelineEventView.php index 0d9b75782f..4da2bfe928 100644 --- a/src/view/phui/PHUITimelineEventView.php +++ b/src/view/phui/PHUITimelineEventView.php @@ -622,9 +622,9 @@ final class PHUITimelineEventView extends AphrontView { )); $content_source = $this->getContentSource(); - $source_email = PhabricatorContentSource::SOURCE_EMAIL; + $source_email = PhabricatorEmailContentSource::SOURCECONST; if ($content_source->getSource() == $source_email) { - $source_id = $content_source->getParam('id'); + $source_id = $content_source->getContentSourceParameter('id'); if ($source_id) { $items[] = id(new PhabricatorActionView()) ->setIcon('fa-envelope-o') From 060f96079def51aa7cb6d32daf7c286c49c45a01 Mon Sep 17 00:00:00 2001 From: epriestley Date: Sat, 26 Mar 2016 11:51:47 -0700 Subject: [PATCH 02/42] Fix Diffusion blame columns when disabling blame Summary: Fixes T10385. Two issues: - `$show_blame` and `$show_color` were improperly swapped. - Code to hide these columns got dropped somewhere, probably in my recent-ish rewrite. Test Plan: - Showed/hid blame. - Showed/hid colors. Reviewers: chad Reviewed By: chad Maniphest Tasks: T10385 Differential Revision: https://secure.phabricator.com/D15528 --- .../controller/DiffusionBrowseController.php | 42 ++++++++++--------- 1 file changed, 22 insertions(+), 20 deletions(-) diff --git a/src/applications/diffusion/controller/DiffusionBrowseController.php b/src/applications/diffusion/controller/DiffusionBrowseController.php index 56d00d53ce..a79613cfa9 100644 --- a/src/applications/diffusion/controller/DiffusionBrowseController.php +++ b/src/applications/diffusion/controller/DiffusionBrowseController.php @@ -995,8 +995,8 @@ final class DiffusionBrowseController extends DiffusionController { array $lines, array $blame_list, array $blame_commits, - $show_color, - $show_blame) { + $show_blame, + $show_color) { $request = $this->getRequest(); $viewer = $this->getViewer(); @@ -1233,27 +1233,29 @@ final class DiffusionBrowseController extends DiffusionController { "\xC2\xAB"); } - $row[] = phutil_tag( - 'th', - array( - 'class' => 'diffusion-blame-link', - ), - $before_link); + if ($show_blame) { + $row[] = phutil_tag( + 'th', + array( + 'class' => 'diffusion-blame-link', + ), + $before_link); - $object_links = array(); - $object_links[] = $commit_link; - if ($revision_link) { - $object_links[] = phutil_tag('span', array(), '/'); - $object_links[] = $revision_link; + $object_links = array(); + $object_links[] = $commit_link; + if ($revision_link) { + $object_links[] = phutil_tag('span', array(), '/'); + $object_links[] = $revision_link; + } + + $row[] = phutil_tag( + 'th', + array( + 'class' => 'diffusion-rev-link', + ), + $object_links); } - $row[] = phutil_tag( - 'th', - array( - 'class' => 'diffusion-rev-link', - ), - $object_links); - $line_link = phutil_tag( 'a', array( From c286d2b441bd1c65f3260665679eaf4019aa3188 Mon Sep 17 00:00:00 2001 From: epriestley Date: Sat, 26 Mar 2016 12:23:07 -0700 Subject: [PATCH 03/42] Don't try to center dialogs horizontally Summary: Fixes T10302. I think we had fixed-width dialog containers in the past (?) but they all handle their own centering now. This was causing them to be slightly off-center as a result, and creating the 7px issue in T10302. Test Plan: - Viewed a wide dialog (task edit). - Viewed a narrow dialog (notification dismissal confirmation). - Viewed dialogs on wide/narrow screens. Reviewers: chad Reviewed By: chad Maniphest Tasks: T10302 Differential Revision: https://secure.phabricator.com/D15529 --- resources/celerity/map.php | 28 +++++++++---------- .../rsrc/externals/javelin/lib/Workflow.js | 2 +- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/resources/celerity/map.php b/resources/celerity/map.php index c710675681..53d42d9c16 100644 --- a/resources/celerity/map.php +++ b/resources/celerity/map.php @@ -8,7 +8,7 @@ return array( 'names' => array( 'core.pkg.css' => '9acdee84', - 'core.pkg.js' => '7d8faf57', + 'core.pkg.js' => 'e5484f37', 'darkconsole.pkg.js' => 'e7393ebb', 'differential.pkg.css' => '7ba78475', 'differential.pkg.js' => 'd0cd0df6', @@ -244,7 +244,7 @@ return array( 'rsrc/externals/javelin/lib/URI.js' => 'c989ade3', 'rsrc/externals/javelin/lib/Vector.js' => '2caa8fb8', 'rsrc/externals/javelin/lib/WebSocket.js' => 'e292eaf4', - 'rsrc/externals/javelin/lib/Workflow.js' => '5b2e3e2b', + 'rsrc/externals/javelin/lib/Workflow.js' => '28cfbdd0', 'rsrc/externals/javelin/lib/__tests__/Cookie.js' => '5ed109e8', 'rsrc/externals/javelin/lib/__tests__/DOM.js' => 'c984504b', 'rsrc/externals/javelin/lib/__tests__/JSON.js' => '837a7d68', @@ -734,7 +734,7 @@ return array( 'javelin-workboard-card' => 'c587b80f', 'javelin-workboard-column' => 'bae58312', 'javelin-workboard-controller' => '55baf5ed', - 'javelin-workflow' => '5b2e3e2b', + 'javelin-workflow' => '28cfbdd0', 'lightbox-attachment-css' => '7acac05d', 'maniphest-batch-editor' => 'b0f0b6d5', 'maniphest-report-css' => '9b9580b7', @@ -1059,6 +1059,17 @@ return array( 'phabricator-drag-and-drop-file-upload', 'phabricator-draggable-list', ), + '28cfbdd0' => array( + 'javelin-stratcom', + 'javelin-request', + 'javelin-dom', + 'javelin-vector', + 'javelin-install', + 'javelin-util', + 'javelin-mask', + 'javelin-uri', + 'javelin-routable', + ), '2926fff2' => array( 'javelin-behavior', 'javelin-dom', @@ -1312,17 +1323,6 @@ return array( 'javelin-vector', 'javelin-magical-init', ), - '5b2e3e2b' => array( - 'javelin-stratcom', - 'javelin-request', - 'javelin-dom', - 'javelin-vector', - 'javelin-install', - 'javelin-util', - 'javelin-mask', - 'javelin-uri', - 'javelin-routable', - ), '5c54cbf3' => array( 'javelin-behavior', 'javelin-stratcom', diff --git a/webroot/rsrc/externals/javelin/lib/Workflow.js b/webroot/rsrc/externals/javelin/lib/Workflow.js index b640adecab..50716b1c07 100644 --- a/webroot/rsrc/externals/javelin/lib/Workflow.js +++ b/webroot/rsrc/externals/javelin/lib/Workflow.js @@ -192,7 +192,7 @@ JX.install('Workflow', { // Use more space if the dialog is large (at least roughly the size // of the viewport). var offset = Math.min(Math.max(20, (v.y - d.y) / 2), 100); - JX.$V((v.x - d.x) / 2, s.y + offset).setPos(this._root); + JX.$V(0, s.y + offset).setPos(this._root); try { JX.DOM.focus(JX.DOM.find(this._root, 'button', '__default__')); From 0330ea575db78db76fb88bf25c5296ba26b9b3df Mon Sep 17 00:00:00 2001 From: lkassianik Date: Wed, 13 Jan 2016 11:33:46 -0800 Subject: [PATCH 04/42] Converting badge recipients from Edge to BadgeAward table Summary: Ref T8996, Convert badge recipients from Edges to actual BadgeAward objects Test Plan: Create badge, award it to recipient. Make sure adding/removing recipients works. (Still need to migrate exisiting recipients to new table and need to create activity feed blurbs) Reviewers: epriestley, #blessed_reviewers Reviewed By: epriestley, #blessed_reviewers Subscribers: chad, Korvin Maniphest Tasks: T8996 Differential Revision: https://secure.phabricator.com/D15014 --- .../sql/autopatches/20160102.badges.award.sql | 10 +++ .../sql/autopatches/20160323.badgemigrate.sql | 6 ++ src/__phutil_library_map__.php | 8 ++ .../PhabricatorBadgesEditController.php | 1 - ...bricatorBadgesEditRecipientsController.php | 24 ++--- ...icatorBadgesRemoveRecipientsController.php | 14 +-- .../PhabricatorBadgesViewController.php | 3 +- .../badges/editor/PhabricatorBadgesEditor.php | 40 +++++++++ .../query/PhabricatorBadgesAwardQuery.php | 87 +++++++++++++++++++ .../badges/query/PhabricatorBadgesQuery.php | 21 ++--- .../badges/storage/PhabricatorBadgesAward.php | 83 ++++++++++++++++++ .../badges/storage/PhabricatorBadgesBadge.php | 19 ++-- .../storage/PhabricatorBadgesTransaction.php | 2 + .../people/query/PhabricatorPeopleQuery.php | 21 ++--- src/view/phui/PHUITimelineView.php | 31 +++---- 15 files changed, 296 insertions(+), 74 deletions(-) create mode 100644 resources/sql/autopatches/20160102.badges.award.sql create mode 100644 resources/sql/autopatches/20160323.badgemigrate.sql create mode 100644 src/applications/badges/query/PhabricatorBadgesAwardQuery.php create mode 100644 src/applications/badges/storage/PhabricatorBadgesAward.php diff --git a/resources/sql/autopatches/20160102.badges.award.sql b/resources/sql/autopatches/20160102.badges.award.sql new file mode 100644 index 0000000000..d637c93650 --- /dev/null +++ b/resources/sql/autopatches/20160102.badges.award.sql @@ -0,0 +1,10 @@ +CREATE TABLE {$NAMESPACE}_badges.badges_award ( + id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, + badgePHID VARBINARY(64) NOT NULL, + recipientPHID VARBINARY(64) NOT NULL, + awarderPHID varbinary(64) NOT NULL, + dateCreated INT UNSIGNED NOT NULL, + dateModified INT UNSIGNED NOT NULL, + UNIQUE KEY `key_badge` (badgePHID, recipientPHID), + KEY `key_recipient` (recipientPHID) +) ENGINE=InnoDB, COLLATE {$COLLATE_TEXT}; diff --git a/resources/sql/autopatches/20160323.badgemigrate.sql b/resources/sql/autopatches/20160323.badgemigrate.sql new file mode 100644 index 0000000000..c7341b287b --- /dev/null +++ b/resources/sql/autopatches/20160323.badgemigrate.sql @@ -0,0 +1,6 @@ +/* PhabricatorBadgeHasRecipientEdgeType::TYPECONST = 59 */ + +INSERT IGNORE INTO {$NAMESPACE}_badges.badges_award + (badgePHID, recipientPHID, awarderPHID, dateCreated, dateModified) + SELECT src, dst, 'PHID-VOID-00000000000000000000', dateCreated, dateCreated + FROM {$NAMESPACE}_badges.edge WHERE type = 59; diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php index 150d2bd8cd..75541320c0 100644 --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -1870,6 +1870,8 @@ phutil_register_library_map(array( 'PhabricatorBadgeHasRecipientEdgeType' => 'applications/badges/edge/PhabricatorBadgeHasRecipientEdgeType.php', 'PhabricatorBadgesApplication' => 'applications/badges/application/PhabricatorBadgesApplication.php', 'PhabricatorBadgesArchiveController' => 'applications/badges/controller/PhabricatorBadgesArchiveController.php', + 'PhabricatorBadgesAward' => 'applications/badges/storage/PhabricatorBadgesAward.php', + 'PhabricatorBadgesAwardQuery' => 'applications/badges/query/PhabricatorBadgesAwardQuery.php', 'PhabricatorBadgesBadge' => 'applications/badges/storage/PhabricatorBadgesBadge.php', 'PhabricatorBadgesCommentController' => 'applications/badges/controller/PhabricatorBadgesCommentController.php', 'PhabricatorBadgesController' => 'applications/badges/controller/PhabricatorBadgesController.php', @@ -6231,6 +6233,12 @@ phutil_register_library_map(array( 'PhabricatorBadgeHasRecipientEdgeType' => 'PhabricatorEdgeType', 'PhabricatorBadgesApplication' => 'PhabricatorApplication', 'PhabricatorBadgesArchiveController' => 'PhabricatorBadgesController', + 'PhabricatorBadgesAward' => array( + 'PhabricatorBadgesDAO', + 'PhabricatorDestructibleInterface', + 'PhabricatorPolicyInterface', + ), + 'PhabricatorBadgesAwardQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', 'PhabricatorBadgesBadge' => array( 'PhabricatorBadgesDAO', 'PhabricatorPolicyInterface', diff --git a/src/applications/badges/controller/PhabricatorBadgesEditController.php b/src/applications/badges/controller/PhabricatorBadgesEditController.php index 3ac1aebe58..725068d7a6 100644 --- a/src/applications/badges/controller/PhabricatorBadgesEditController.php +++ b/src/applications/badges/controller/PhabricatorBadgesEditController.php @@ -2,7 +2,6 @@ final class PhabricatorBadgesEditController extends PhabricatorBadgesController { - public function handleRequest(AphrontRequest $request) { return id(new PhabricatorBadgesEditEngine()) ->setController($this) diff --git a/src/applications/badges/controller/PhabricatorBadgesEditRecipientsController.php b/src/applications/badges/controller/PhabricatorBadgesEditRecipientsController.php index 70e3d8f029..a73c6777af 100644 --- a/src/applications/badges/controller/PhabricatorBadgesEditRecipientsController.php +++ b/src/applications/badges/controller/PhabricatorBadgesEditRecipientsController.php @@ -6,6 +6,7 @@ final class PhabricatorBadgesEditRecipientsController public function handleRequest(AphrontRequest $request) { $viewer = $request->getViewer(); $id = $request->getURIData('id'); + $xactions = array(); $badge = id(new PhabricatorBadgesQuery()) ->setViewer($viewer) @@ -21,30 +22,23 @@ final class PhabricatorBadgesEditRecipientsController return new Aphront404Response(); } - $recipient_phids = $badge->getRecipientPHIDs(); $view_uri = $this->getApplicationURI('view/'.$badge->getID().'/'); + $awards = $badge->getAwards(); + $recipient_phids = mpull($awards, 'getRecipientPHID'); if ($request->isFormPost()) { - $recipient_spec = array(); - - $remove = $request->getStr('remove'); - if ($remove) { - $recipient_spec['-'] = array_fuse(array($remove)); - } + $award_phids = array(); $add_recipients = $request->getArr('phids'); if ($add_recipients) { - $recipient_spec['+'] = array_fuse($add_recipients); + foreach ($add_recipients as $phid) { + $award_phids[] = $phid; + } } - $type_recipient = PhabricatorBadgeHasRecipientEdgeType::EDGECONST; - - $xactions = array(); - $xactions[] = id(new PhabricatorBadgesTransaction()) - ->setTransactionType(PhabricatorTransactions::TYPE_EDGE) - ->setMetadataValue('edge:type', $type_recipient) - ->setNewValue($recipient_spec); + ->setTransactionType(PhabricatorBadgesTransaction::TYPE_AWARD) + ->setNewValue($award_phids); $editor = id(new PhabricatorBadgesEditor($badge)) ->setActor($viewer) diff --git a/src/applications/badges/controller/PhabricatorBadgesRemoveRecipientsController.php b/src/applications/badges/controller/PhabricatorBadgesRemoveRecipientsController.php index bc467b703d..c77a5f33ea 100644 --- a/src/applications/badges/controller/PhabricatorBadgesRemoveRecipientsController.php +++ b/src/applications/badges/controller/PhabricatorBadgesRemoveRecipientsController.php @@ -21,7 +21,8 @@ final class PhabricatorBadgesRemoveRecipientsController return new Aphront404Response(); } - $recipient_phids = $badge->getRecipientPHIDs(); + $awards = $badge->getAwards(); + $recipient_phids = mpull($awards, 'getRecipientPHID'); $remove_phid = $request->getStr('phid'); if (!in_array($remove_phid, $recipient_phids)) { @@ -31,17 +32,10 @@ final class PhabricatorBadgesRemoveRecipientsController $view_uri = $this->getApplicationURI('view/'.$badge->getID().'/'); if ($request->isFormPost()) { - $recipient_spec = array(); - $recipient_spec['-'] = array($remove_phid => $remove_phid); - - $type_recipient = PhabricatorBadgeHasRecipientEdgeType::EDGECONST; - $xactions = array(); - $xactions[] = id(new PhabricatorBadgesTransaction()) - ->setTransactionType(PhabricatorTransactions::TYPE_EDGE) - ->setMetadataValue('edge:type', $type_recipient) - ->setNewValue($recipient_spec); + ->setTransactionType(PhabricatorBadgesTransaction::TYPE_REVOKE) + ->setNewValue(array($remove_phid)); $editor = id(new PhabricatorBadgesEditor($badge)) ->setActor($viewer) diff --git a/src/applications/badges/controller/PhabricatorBadgesViewController.php b/src/applications/badges/controller/PhabricatorBadgesViewController.php index fac82ccc8d..0f3077de0b 100644 --- a/src/applications/badges/controller/PhabricatorBadgesViewController.php +++ b/src/applications/badges/controller/PhabricatorBadgesViewController.php @@ -50,7 +50,8 @@ final class PhabricatorBadgesViewController $badge, new PhabricatorBadgesTransactionQuery()); - $recipient_phids = $badge->getRecipientPHIDs(); + $awards = $badge->getAwards(); + $recipient_phids = mpull($awards, 'getRecipientPHID'); $recipient_phids = array_reverse($recipient_phids); $handles = $this->loadViewerHandles($recipient_phids); diff --git a/src/applications/badges/editor/PhabricatorBadgesEditor.php b/src/applications/badges/editor/PhabricatorBadgesEditor.php index fd0b14ad46..af3def28c5 100644 --- a/src/applications/badges/editor/PhabricatorBadgesEditor.php +++ b/src/applications/badges/editor/PhabricatorBadgesEditor.php @@ -20,6 +20,8 @@ final class PhabricatorBadgesEditor $types[] = PhabricatorBadgesTransaction::TYPE_ICON; $types[] = PhabricatorBadgesTransaction::TYPE_STATUS; $types[] = PhabricatorBadgesTransaction::TYPE_QUALITY; + $types[] = PhabricatorBadgesTransaction::TYPE_AWARD; + $types[] = PhabricatorBadgesTransaction::TYPE_REVOKE; $types[] = PhabricatorTransactions::TYPE_COMMENT; $types[] = PhabricatorTransactions::TYPE_EDGE; @@ -44,6 +46,11 @@ final class PhabricatorBadgesEditor return $object->getQuality(); case PhabricatorBadgesTransaction::TYPE_STATUS: return $object->getStatus(); + case PhabricatorBadgesTransaction::TYPE_AWARD: + $award_phids = mpull($object->getAwards(), 'getRecipientPHID'); + return $award_phids; + case PhabricatorBadgesTransaction::TYPE_REVOKE: + return null; } return parent::getCustomTransactionOldValue($object, $xaction); @@ -60,6 +67,8 @@ final class PhabricatorBadgesEditor case PhabricatorBadgesTransaction::TYPE_ICON: case PhabricatorBadgesTransaction::TYPE_STATUS: case PhabricatorBadgesTransaction::TYPE_QUALITY: + case PhabricatorBadgesTransaction::TYPE_AWARD: + case PhabricatorBadgesTransaction::TYPE_REVOKE: return $xaction->getNewValue(); } @@ -90,6 +99,9 @@ final class PhabricatorBadgesEditor case PhabricatorBadgesTransaction::TYPE_STATUS: $object->setStatus($xaction->getNewValue()); return; + case PhabricatorBadgesTransaction::TYPE_AWARD: + case PhabricatorBadgesTransaction::TYPE_REVOKE: + return; } return parent::applyCustomInternalTransaction($object, $xaction); @@ -108,6 +120,34 @@ final class PhabricatorBadgesEditor case PhabricatorBadgesTransaction::TYPE_STATUS: case PhabricatorBadgesTransaction::TYPE_QUALITY: return; + case PhabricatorBadgesTransaction::TYPE_REVOKE: + $revoked_recipient_phids = $xaction->getNewValue(); + $awards = $object->getAwards(); + $awards = mpull($awards, null, 'getRecipientPHID'); + + foreach ($revoked_recipient_phids as $phid) { + $awards[$phid]->delete(); + } + $object->attachAwards($awards); + return; + case PhabricatorBadgesTransaction::TYPE_AWARD: + $recipient_phids = $xaction->getNewValue(); + $awards = $object->getAwards(); + $awards = mpull($awards, null, 'getRecipientPHID'); + + foreach ($recipient_phids as $phid) { + $award = idx($awards, $phid); + if (!$award) { + $award = PhabricatorBadgesAward::initializeNewBadgesAward( + $this->getActor(), + $object, + $phid); + $award->save(); + $awards[] = $award; + } + } + $object->attachAwards($awards); + return; } return parent::applyCustomExternalTransaction($object, $xaction); diff --git a/src/applications/badges/query/PhabricatorBadgesAwardQuery.php b/src/applications/badges/query/PhabricatorBadgesAwardQuery.php new file mode 100644 index 0000000000..355feec066 --- /dev/null +++ b/src/applications/badges/query/PhabricatorBadgesAwardQuery.php @@ -0,0 +1,87 @@ +setViewer($this->getViewer()) + ->withRecipientPHIDs(mpull($awards, null, 'getRecipientPHID')) + ->execute(); + + $badges = mpull($badges, null, 'getPHID'); + + foreach ($awards as $key => $award) { + $award_badge = idx($badges, $award->getBadgePHID()); + if ($award_badge === null) { + $this->didRejectResult($award); + unset($awards[$key]); + continue; + } + + $award->attachBadge($award_badge); + } + + return $awards; + } + + public function withBadgePHIDs(array $phids) { + $this->badgePHIDs = $phids; + return $this; + } + + public function withRecipientPHIDs(array $phids) { + $this->recipientPHIDs = $phids; + return $this; + } + + public function withAwarderPHIDs(array $phids) { + $this->awarderPHIDs = $phids; + return $this; + } + + protected function loadPage() { + return $this->loadStandardPage($this->newResultObject()); + } + + public function newResultObject() { + return new PhabricatorBadgesAward(); + } + + protected function buildWhereClauseParts(AphrontDatabaseConnection $conn) { + $where = parent::buildWhereClauseParts($conn); + + if ($this->badgePHIDs !== null) { + $where[] = qsprintf( + $conn, + 'badgePHID IN (%Ls)', + $this->badgePHIDs); + } + + if ($this->recipientPHIDs !== null) { + $where[] = qsprintf( + $conn, + 'recipientPHID IN (%Ls)', + $this->recipientPHIDs); + } + + if ($this->awarderPHIDs !== null) { + $where[] = qsprintf( + $conn, + 'awarderPHID IN (%Ls)', + $this->awarderPHIDs); + } + + return $where; + } + + public function getQueryApplicationClass() { + return 'PhabricatorBadgesApplication'; + } + +} diff --git a/src/applications/badges/query/PhabricatorBadgesQuery.php b/src/applications/badges/query/PhabricatorBadgesQuery.php index 91d7111253..fce8b3731f 100644 --- a/src/applications/badges/query/PhabricatorBadgesQuery.php +++ b/src/applications/badges/query/PhabricatorBadgesQuery.php @@ -50,22 +50,17 @@ final class PhabricatorBadgesQuery } protected function didFilterPage(array $badges) { - if ($this->needRecipients) { - $edge_query = id(new PhabricatorEdgeQuery()) - ->withSourcePHIDs(mpull($badges, 'getPHID')) - ->withEdgeTypes( - array( - PhabricatorBadgeHasRecipientEdgeType::EDGECONST, - )); - $edge_query->execute(); + $query = id(new PhabricatorBadgesAwardQuery()) + ->setViewer($this->getViewer()) + ->withBadgePHIDs(mpull($badges, 'getPHID')) + ->execute(); + + $awards = mgroup($query, 'getBadgePHID'); foreach ($badges as $badge) { - $phids = $edge_query->getDestinationPHIDs( - array( - $badge->getPHID(), - )); - $badge->attachRecipientPHIDs($phids); + $badge_awards = idx($awards, $badge->getPHID(), array()); + $badge->attachAwards($badge_awards); } } diff --git a/src/applications/badges/storage/PhabricatorBadgesAward.php b/src/applications/badges/storage/PhabricatorBadgesAward.php new file mode 100644 index 0000000000..851ac87002 --- /dev/null +++ b/src/applications/badges/storage/PhabricatorBadgesAward.php @@ -0,0 +1,83 @@ +setRecipientPHID($recipient_phid) + ->setBadgePHID($badge->getPHID()) + ->setAwarderPHID($actor->getPHID()) + ->attachBadge($badge); + } + + protected function getConfiguration() { + return array( + self::CONFIG_KEY_SCHEMA => array( + 'key_badge' => array( + 'columns' => array('badgePHID', 'recipientPHID'), + 'unique' => true, + ), + 'key_recipient' => array( + 'columns' => array('recipientPHID'), + ), + ), + ) + parent::getConfiguration(); + } + + public function attachBadge(PhabricatorBadgesBadge $badge) { + $this->badge = $badge; + return $this; + } + + public function getBadge() { + return $this->assertAttached($this->badge); + } + + +/* -( PhabricatorDestructibleInterface )----------------------------------- */ + + + public function destroyObjectPermanently( + PhabricatorDestructionEngine $engine) { + + $this->openTransaction(); + $this->delete(); + $this->saveTransaction(); + } + + +/* -( PhabricatorPolicyInterface )----------------------------------------- */ + + + public function getCapabilities() { + return array( + PhabricatorPolicyCapability::CAN_VIEW, + PhabricatorPolicyCapability::CAN_EDIT, + ); + } + + public function getPolicy($capability) { + return $this->getBadge()->getPolicy($capability); + } + + public function hasAutomaticCapability($capability, PhabricatorUser $viewer) { + return false; + } + + public function describeAutomaticCapability($capability) { + return null; + } + +} diff --git a/src/applications/badges/storage/PhabricatorBadgesBadge.php b/src/applications/badges/storage/PhabricatorBadgesBadge.php index d32a46a803..2959111dc4 100644 --- a/src/applications/badges/storage/PhabricatorBadgesBadge.php +++ b/src/applications/badges/storage/PhabricatorBadgesBadge.php @@ -19,7 +19,7 @@ final class PhabricatorBadgesBadge extends PhabricatorBadgesDAO protected $status; protected $creatorPHID; - private $recipientPHIDs = self::ATTACHABLE; + private $awards = self::ATTACHABLE; const STATUS_ACTIVE = 'open'; const STATUS_ARCHIVED = 'closed'; @@ -102,13 +102,13 @@ final class PhabricatorBadgesBadge extends PhabricatorBadgesDAO return ($this->getStatus() == self::STATUS_ARCHIVED); } - public function attachRecipientPHIDs(array $phids) { - $this->recipientPHIDs = $phids; + public function attachAwards(array $awards) { + $this->awards = $awards; return $this; } - public function getRecipientPHIDs() { - return $this->assertAttached($this->recipientPHIDs); + public function getAwards() { + return $this->assertAttached($this->awards); } public function getViewURI() { @@ -197,6 +197,15 @@ final class PhabricatorBadgesBadge extends PhabricatorBadgesDAO public function destroyObjectPermanently( PhabricatorDestructionEngine $engine) { + $awards = id(new PhabricatorBadgesAwardQuery()) + ->setViewer($engine->getViewer()) + ->withBadgePHIDs(array($this->getPHID())) + ->execute(); + + foreach ($awards as $award) { + $engine->destroyObjectPermanently($award); + } + $this->openTransaction(); $this->delete(); $this->saveTransaction(); diff --git a/src/applications/badges/storage/PhabricatorBadgesTransaction.php b/src/applications/badges/storage/PhabricatorBadgesTransaction.php index c2e934390d..f25c629c96 100644 --- a/src/applications/badges/storage/PhabricatorBadgesTransaction.php +++ b/src/applications/badges/storage/PhabricatorBadgesTransaction.php @@ -9,6 +9,8 @@ final class PhabricatorBadgesTransaction const TYPE_ICON = 'badges:icon'; const TYPE_STATUS = 'badges:status'; const TYPE_FLAVOR = 'badges:flavor'; + const TYPE_AWARD = 'badges:award'; + const TYPE_REVOKE = 'badges:revoke'; const MAILTAG_DETAILS = 'badges:details'; const MAILTAG_COMMENT = 'badges:comment'; diff --git a/src/applications/people/query/PhabricatorPeopleQuery.php b/src/applications/people/query/PhabricatorPeopleQuery.php index 2932d8c853..0bdb9fab2d 100644 --- a/src/applications/people/query/PhabricatorPeopleQuery.php +++ b/src/applications/people/query/PhabricatorPeopleQuery.php @@ -155,20 +155,17 @@ final class PhabricatorPeopleQuery } if ($this->needBadges) { - $edge_query = id(new PhabricatorEdgeQuery()) - ->withSourcePHIDs(mpull($users, 'getPHID')) - ->withEdgeTypes( - array( - PhabricatorRecipientHasBadgeEdgeType::EDGECONST, - )); - $edge_query->execute(); + $awards = id(new PhabricatorBadgesAwardQuery()) + ->setViewer($this->getViewer()) + ->withRecipientPHIDs(mpull($users, 'getPHID')) + ->execute(); + + $awards = mgroup($awards, 'getRecipientPHID'); foreach ($users as $user) { - $phids = $edge_query->getDestinationPHIDs( - array( - $user->getPHID(), - )); - $user->attachBadgePHIDs($phids); + $user_awards = idx($awards, $user->getPHID(), array()); + $badge_phids = mpull($user_awards, 'getBadgePHID'); + $user->attachBadgePHIDs($badge_phids); } } diff --git a/src/view/phui/PHUITimelineView.php b/src/view/phui/PHUITimelineView.php index 2718fbd9f2..729320ebd1 100644 --- a/src/view/phui/PHUITimelineView.php +++ b/src/view/phui/PHUITimelineView.php @@ -250,31 +250,28 @@ final class PHUITimelineView extends AphrontView { return; } - $edges = id(new PhabricatorEdgeQuery()) - ->withSourcePHIDs($user_phids) - ->withEdgeTypes(array($badge_edge_type)); - $edges->execute(); - $badge_phids = $edges->getDestinationPHIDs(); - if (!$badge_phids) { - return; - } - - $all_badges = id(new PhabricatorBadgesQuery()) - ->setViewer($viewer) - ->withPHIDs($badge_phids) - ->withStatuses(array(PhabricatorBadgesBadge::STATUS_ACTIVE)) + $awards = id(new PhabricatorBadgesAwardQuery()) + ->setViewer($this->getViewer()) + ->withRecipientPHIDs($user_phids) ->execute(); - $all_badges = mpull($all_badges, null, 'getPHID'); + + $awards = mgroup($awards, 'getRecipientPHID'); foreach ($events as $event) { - $author_phid = $event->getAuthorPHID(); - $event_phids = $edges->getDestinationPHIDs(array($author_phid)); - $badges = array_select_keys($all_badges, $event_phids); + $author_awards = idx($awards, $event->getAuthorPHID(), array()); + $badges = array(); + foreach ($author_awards as $award) { + $badge = $award->getBadge(); + if ($badge->getStatus() == PhabricatorBadgesBadge::STATUS_ACTIVE) { + $badges[$award->getBadgePHID()] = $badge; + } + } // TODO: Pick the "best" badges in some smart way. For now, just pick // the first two. $badges = array_slice($badges, 0, 2); + foreach ($badges as $badge) { $badge_view = id(new PHUIBadgeMiniView()) ->setIcon($badge->getIcon()) From 6ad70d2236c2f74b65a1fa05076b0cfa99041bfb Mon Sep 17 00:00:00 2001 From: Chad Little Date: Sat, 26 Mar 2016 11:54:55 -0700 Subject: [PATCH 05/42] Convert Alamanc edit forms to new UI Summary: Adds headers, new layout to edit panels on Almanac. Test Plan: Pull up each edit panel in sandbox, save form. Reviewers: epriestley Reviewed By: epriestley Subscribers: Korvin Differential Revision: https://secure.phabricator.com/D15527 --- .../AlmanacBindingEditController.php | 22 ++++++++++++++----- .../controller/AlmanacConsoleController.php | 17 +++++++++----- .../AlmanacInterfaceEditController.php | 22 ++++++++++++++----- .../AlmanacServiceEditController.php | 16 ++++++++++++-- 4 files changed, 59 insertions(+), 18 deletions(-) diff --git a/src/applications/almanac/controller/AlmanacBindingEditController.php b/src/applications/almanac/controller/AlmanacBindingEditController.php index f20011ded9..5f1fe30043 100644 --- a/src/applications/almanac/controller/AlmanacBindingEditController.php +++ b/src/applications/almanac/controller/AlmanacBindingEditController.php @@ -99,25 +99,35 @@ final class AlmanacBindingEditController $box = id(new PHUIObjectBoxView()) ->setValidationException($validation_exception) - ->setHeaderText($title) + ->setHeaderText(pht('Binding')) + ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) ->appendChild($form); $crumbs = $this->buildApplicationCrumbs(); $crumbs->addTextCrumb($service->getName(), $service_uri); if ($is_new) { $crumbs->addTextCrumb(pht('Create Binding')); + $header = id(new PHUIHeaderView()) + ->setHeader(pht('Create Binding')) + ->setHeaderIcon('fa-plus-square'); } else { $crumbs->addTextCrumb(pht('Edit Binding')); + $header = id(new PHUIHeaderView()) + ->setHeader(pht('Create Binding')) + ->setHeaderIcon('fa-pencil'); } + $crumbs->setBorder(true); + + $view = id(new PHUITwoColumnView()) + ->setHeader($header) + ->setFooter(array( + $box, + )); return $this->newPage() ->setTitle($title) ->setCrumbs($crumbs) - ->appendChild( - array( - $box, - )); - + ->appendChild($view); } } diff --git a/src/applications/almanac/controller/AlmanacConsoleController.php b/src/applications/almanac/controller/AlmanacConsoleController.php index 9b83db9daa..cd9ebf610a 100644 --- a/src/applications/almanac/controller/AlmanacConsoleController.php +++ b/src/applications/almanac/controller/AlmanacConsoleController.php @@ -61,18 +61,25 @@ final class AlmanacConsoleController extends AlmanacController { $crumbs = $this->buildApplicationCrumbs(); $crumbs->addTextCrumb(pht('Console')); + $crumbs->setBorder(true); $box = id(new PHUIObjectBoxView()) - ->setHeaderText(pht('Console')) ->setObjectList($menu); + $header = id(new PHUIHeaderView()) + ->setHeader(pht('Almanac Console')) + ->setHeaderIcon('fa-server'); + + $view = id(new PHUITwoColumnView()) + ->setHeader($header) + ->setFooter(array( + $box, + )); + return $this->newPage() ->setTitle(pht('Almanac Console')) ->setCrumbs($crumbs) - ->appendChild( - array( - $box, - )); + ->appendChild($view); } diff --git a/src/applications/almanac/controller/AlmanacInterfaceEditController.php b/src/applications/almanac/controller/AlmanacInterfaceEditController.php index 6d750bfbf5..d223360003 100644 --- a/src/applications/almanac/controller/AlmanacInterfaceEditController.php +++ b/src/applications/almanac/controller/AlmanacInterfaceEditController.php @@ -131,24 +131,36 @@ final class AlmanacInterfaceEditController $box = id(new PHUIObjectBoxView()) ->setValidationException($validation_exception) - ->setHeaderText($title) + ->setHeaderText(pht('Interface')) + ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) ->setForm($form); $crumbs = $this->buildApplicationCrumbs(); $crumbs->addTextCrumb($device->getName(), $device_uri); if ($is_new) { $crumbs->addTextCrumb(pht('Create Interface')); + $header = id(new PHUIHeaderView()) + ->setHeader(pht('Create Interface')) + ->setHeaderIcon('fa-plus-square'); } else { $crumbs->addTextCrumb(pht('Edit Interface')); + $header = id(new PHUIHeaderView()) + ->setHeader(pht('Edit Interface')) + ->setHeaderIcon('fa-pencil'); } + $crumbs->setBorder(true); + + $view = id(new PHUITwoColumnView()) + ->setHeader($header) + ->setFooter(array( + $box, + )); return $this->newPage() ->setTitle($title) ->setCrumbs($crumbs) - ->appendChild( - array( - $box, - )); + ->appendChild($view); + } } diff --git a/src/applications/almanac/controller/AlmanacServiceEditController.php b/src/applications/almanac/controller/AlmanacServiceEditController.php index b09deaa95d..710e27a966 100644 --- a/src/applications/almanac/controller/AlmanacServiceEditController.php +++ b/src/applications/almanac/controller/AlmanacServiceEditController.php @@ -75,8 +75,12 @@ final class AlmanacServiceEditController $crumbs = $this->buildApplicationCrumbs(); $crumbs->addTextCrumb(pht('Create Service')); + $crumbs->setBorder(true); $title = pht('Choose Service Type'); + $header = id(new PHUIHeaderView()) + ->setHeader(pht('Create Service')) + ->setHeaderIcon('fa-plus-square'); $form = id(new AphrontFormView()) ->setUser($viewer) @@ -88,13 +92,21 @@ final class AlmanacServiceEditController $box = id(new PHUIObjectBoxView()) ->setFormErrors($errors) - ->setHeaderText($title) + ->setHeaderText(pht('Service')) + ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) ->setForm($form); + $view = id(new PHUITwoColumnView()) + ->setHeader($header) + ->setFooter(array( + $box, + )); + return $this->newPage() ->setTitle($title) ->setCrumbs($crumbs) - ->appendChild($box); + ->appendChild($view); + } } From dccce146211b4bf3e6d1cce38b4e28ebb70f6b2c Mon Sep 17 00:00:00 2001 From: Chad Little Date: Sun, 27 Mar 2016 13:07:53 -0700 Subject: [PATCH 06/42] Update misc bits of Ponder to TwoColumnView Summary: Brings in the new headers, layout into Ponder History, editing. Test Plan: Edit Question, Edit Answer, Question History, Answer History Reviewers: epriestley Reviewed By: epriestley Subscribers: Korvin Differential Revision: https://secure.phabricator.com/D15530 --- .../controller/PonderAnswerEditController.php | 26 +++++++++++------ .../PonderAnswerHistoryController.php | 22 ++++++++------ .../PonderQuestionCommentController.php | 5 ---- .../PonderQuestionEditController.php | 29 +++++++++++++------ .../PonderQuestionHistoryController.php | 21 +++++++++----- 5 files changed, 63 insertions(+), 40 deletions(-) diff --git a/src/applications/ponder/controller/PonderAnswerEditController.php b/src/applications/ponder/controller/PonderAnswerEditController.php index ff2fd35920..3362e15834 100644 --- a/src/applications/ponder/controller/PonderAnswerEditController.php +++ b/src/applications/ponder/controller/PonderAnswerEditController.php @@ -91,10 +91,16 @@ final class PonderAnswerEditController extends PonderController { $crumbs = $this->buildApplicationCrumbs(); $crumbs->addTextCrumb("Q{$qid}", $answer_uri); $crumbs->addTextCrumb(pht('Edit Answer')); + $crumbs->setBorder(true); - $form_box = id(new PHUIObjectBoxView()) - ->setHeaderText(pht('Edit Answer')) + $header = id(new PHUIHeaderView()) + ->setHeader(pht('Edit Answer')) + ->setHeaderIcon('fa-pencil'); + + $box = id(new PHUIObjectBoxView()) + ->setHeaderText(pht('Answer')) ->setFormErrors($errors) + ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) ->setForm($form); $preview = id(new PHUIRemarkupPreviewPanel()) @@ -102,15 +108,17 @@ final class PonderAnswerEditController extends PonderController { ->setControlID($answer_content_id) ->setPreviewURI($this->getApplicationURI('preview/')); - return $this->buildApplicationPage( - array( - $crumbs, - $form_box, + $view = id(new PHUITwoColumnView()) + ->setHeader($header) + ->setFooter(array( + $box, $preview, - ), - array( - 'title' => pht('Edit Answer'), )); + return $this->newPage() + ->setTitle(pht('Edit Answer')) + ->setCrumbs($crumbs) + ->appendChild($view); + } } diff --git a/src/applications/ponder/controller/PonderAnswerHistoryController.php b/src/applications/ponder/controller/PonderAnswerHistoryController.php index 136cd8532e..9d7b96335a 100644 --- a/src/applications/ponder/controller/PonderAnswerHistoryController.php +++ b/src/applications/ponder/controller/PonderAnswerHistoryController.php @@ -18,7 +18,6 @@ final class PonderAnswerHistoryController extends PonderController { return new Aphront404Response(); } - $timeline = $this->buildTransactionTimeline( $answer, new PonderAnswerTransactionQuery()); @@ -32,15 +31,20 @@ final class PonderAnswerHistoryController extends PonderController { $crumbs->addTextCrumb("Q{$qid}", "/Q{$qid}"); $crumbs->addTextCrumb("A{$aid}", "/Q{$qid}#{$aid}"); $crumbs->addTextCrumb(pht('History')); + $crumbs->setBorder(true); - return $this->buildApplicationPage( - array( - $crumbs, - $timeline, - ), - array( - 'title' => pht('Answer History'), - )); + $header = id(new PHUIHeaderView()) + ->setHeader(pht('Answer History')) + ->setHeaderIcon('fa-history'); + + $view = id(new PHUITwoColumnView()) + ->setHeader($header) + ->setFooter($timeline); + + return $this->newPage() + ->setTitle(pht('Answer History')) + ->setCrumbs($crumbs) + ->appendChild($view); } } diff --git a/src/applications/ponder/controller/PonderQuestionCommentController.php b/src/applications/ponder/controller/PonderQuestionCommentController.php index 4834d8040c..84c276cd5d 100644 --- a/src/applications/ponder/controller/PonderQuestionCommentController.php +++ b/src/applications/ponder/controller/PonderQuestionCommentController.php @@ -19,7 +19,6 @@ final class PonderQuestionCommentController extends PonderController { } $is_preview = $request->isPreviewRequest(); -// $draft = PhabricatorDraft::buildFromRequest($request); $qid = $question->getID(); $view_uri = "/Q{$qid}"; @@ -45,10 +44,6 @@ final class PonderQuestionCommentController extends PonderController { ->setException($ex); } -// if ($draft) { -// $draft->replaceOrDelete(); -// } - if ($request->isAjax() && $is_preview) { return id(new PhabricatorApplicationTransactionResponse()) ->setViewer($viewer) diff --git a/src/applications/ponder/controller/PonderQuestionEditController.php b/src/applications/ponder/controller/PonderQuestionEditController.php index d31db7c157..907094c7e9 100644 --- a/src/applications/ponder/controller/PonderQuestionEditController.php +++ b/src/applications/ponder/controller/PonderQuestionEditController.php @@ -183,26 +183,37 @@ final class PonderQuestionEditController extends PonderController { $crumbs->addTextCrumb("Q{$id}", "/Q{$id}"); $crumbs->addTextCrumb(pht('Edit')); $title = pht('Edit Question'); + $header = id(new PHUIHeaderView()) + ->setHeader($title) + ->setHeaderIcon('fa-pencil'); } else { $crumbs->addTextCrumb(pht('Ask Question')); $title = pht('Ask New Question'); + $header = id(new PHUIHeaderView()) + ->setHeader($title) + ->setHeaderIcon('fa-plus-square'); } + $crumbs->setBorder(true); - $form_box = id(new PHUIObjectBoxView()) - ->setHeaderText($title) + $box = id(new PHUIObjectBoxView()) + ->setHeaderText(pht('Question')) ->setFormErrors($errors) + ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) ->setForm($form); - return $this->buildApplicationPage( - array( - $crumbs, - $form_box, + $view = id(new PHUITwoColumnView()) + ->setHeader($header) + ->setFooter(array( + $box, $preview, $answer_preview, - ), - array( - 'title' => $title, )); + + return $this->newPage() + ->setTitle($title) + ->setCrumbs($crumbs) + ->appendChild($view); + } } diff --git a/src/applications/ponder/controller/PonderQuestionHistoryController.php b/src/applications/ponder/controller/PonderQuestionHistoryController.php index e7801ab4b1..21cc2ed064 100644 --- a/src/applications/ponder/controller/PonderQuestionHistoryController.php +++ b/src/applications/ponder/controller/PonderQuestionHistoryController.php @@ -29,15 +29,20 @@ final class PonderQuestionHistoryController extends PonderController { $crumbs->setBorder(true); $crumbs->addTextCrumb("Q{$qid}", "/Q{$qid}"); $crumbs->addTextCrumb(pht('History')); + $crumbs->setBorder(true); - return $this->buildApplicationPage( - array( - $crumbs, - $timeline, - ), - array( - 'title' => pht('Question History'), - )); + $header = id(new PHUIHeaderView()) + ->setHeader($question->getTitle()) + ->setHeaderIcon('fa-history'); + + $view = id(new PHUITwoColumnView()) + ->setHeader($header) + ->setFooter($timeline); + + return $this->newPage() + ->setTitle(pht('Question History')) + ->setCrumbs($crumbs) + ->appendChild($view); } } From ef320613875e849e614471f02cd339f956f3e20c Mon Sep 17 00:00:00 2001 From: epriestley Date: Mon, 28 Mar 2016 09:10:05 -0700 Subject: [PATCH 07/42] Give emphasized text an italic style inside normal-style headers inside italic-style blockquotes in Remarkup Summary: Fixes T10686. Test Plan: {F1193658} Reviewers: chad Reviewed By: chad Maniphest Tasks: T10686 Differential Revision: https://secure.phabricator.com/D15532 --- webroot/rsrc/css/core/remarkup.css | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/webroot/rsrc/css/core/remarkup.css b/webroot/rsrc/css/core/remarkup.css index 7b537f5d67..2313939f4c 100644 --- a/webroot/rsrc/css/core/remarkup.css +++ b/webroot/rsrc/css/core/remarkup.css @@ -182,6 +182,8 @@ } .phabricator-remarkup blockquote em { + /* In blockquote bodies, default text is italic so emphasized text should + be normal. */ font-style: normal; } @@ -190,6 +192,12 @@ padding-bottom: 4px; } +.phabricator-remarkup blockquote div.remarkup-reply-head em { + /* In blockquote headers, default text is normal so emphasized text should + be italic. See T10686. */ + font-style: italic; +} + .phabricator-remarkup blockquote div.remarkup-reply-head .phui-tag-core { background-color: transparent; From 02d670b156939f2b02da5bae7c44554d32235146 Mon Sep 17 00:00:00 2001 From: epriestley Date: Mon, 28 Mar 2016 09:14:17 -0700 Subject: [PATCH 08/42] Fibrous legumes. --- resources/celerity/map.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/resources/celerity/map.php b/resources/celerity/map.php index 53d42d9c16..65cda5a557 100644 --- a/resources/celerity/map.php +++ b/resources/celerity/map.php @@ -7,7 +7,7 @@ */ return array( 'names' => array( - 'core.pkg.css' => '9acdee84', + 'core.pkg.css' => '26886078', 'core.pkg.js' => 'e5484f37', 'darkconsole.pkg.js' => 'e7393ebb', 'differential.pkg.css' => '7ba78475', @@ -104,7 +104,7 @@ return array( 'rsrc/css/application/tokens/tokens.css' => '3d0f239e', 'rsrc/css/application/uiexample/example.css' => '528b19de', 'rsrc/css/core/core.css' => 'd0801452', - 'rsrc/css/core/remarkup.css' => 'fc228f08', + 'rsrc/css/core/remarkup.css' => '2c9ed46f', 'rsrc/css/core/syntax.css' => '9fd11da8', 'rsrc/css/core/z-index.css' => '5b6fcf3f', 'rsrc/css/diviner/diviner-shared.css' => 'aa3656aa', @@ -771,7 +771,7 @@ return array( 'phabricator-object-selector-css' => '85ee8ce6', 'phabricator-phtize' => 'd254d646', 'phabricator-prefab' => 'e67df814', - 'phabricator-remarkup-css' => 'fc228f08', + 'phabricator-remarkup-css' => '2c9ed46f', 'phabricator-search-results-css' => '7dea472c', 'phabricator-shaped-request' => '7cbe244b', 'phabricator-side-menu-view-css' => '3a3d9f41', From a939bbc4fa213a7323a53e88b1e8f52f3be5dc83 Mon Sep 17 00:00:00 2001 From: Chad Little Date: Mon, 28 Mar 2016 09:05:22 -0700 Subject: [PATCH 09/42] Update EditEngine for two column Summary: Cleans up EditEngine, adds new layout to EditEngine and descendents Test Plan: Test creating a new form, reordering, marking and unmarking defaults. View new forms. Reviewers: epriestley Reviewed By: epriestley Subscribers: Korvin Differential Revision: https://secure.phabricator.com/D15531 --- resources/celerity/map.php | 4 +- .../AlmanacBindingPropertyEditEngine.php | 4 + .../editor/AlmanacDeviceEditEngine.php | 4 + .../AlmanacDevicePropertyEditEngine.php | 4 + .../editor/AlmanacNamespaceEditEngine.php | 4 + .../editor/AlmanacNetworkEditEngine.php | 4 + .../editor/AlmanacServiceEditEngine.php | 4 + .../AlmanacServicePropertyEditEngine.php | 4 + .../editor/PhabricatorBadgesEditEngine.php | 6 +- .../editor/DrydockBlueprintEditEngine.php | 4 + .../HarbormasterBuildPlanEditEngine.php | 4 + .../maniphest/editor/ManiphestEditEngine.php | 6 +- .../nuance/editor/NuanceQueueEditEngine.php | 4 + .../nuance/editor/NuanceSourceEditEngine.php | 4 + .../PhabricatorOwnersPackageEditEngine.php | 6 +- .../editor/PhabricatorPasteEditEngine.php | 4 + .../phame/editor/PhameBlogEditEngine.php | 4 + .../phame/editor/PhamePostEditEngine.php | 4 + .../engine/PhabricatorProjectEditEngine.php | 6 +- .../PhabricatorProfilePanelEditEngine.php | 4 + ...tEngineConfigurationDefaultsController.php | 20 ++++- ...rEditEngineConfigurationViewController.php | 79 +++++++++++-------- .../editengine/PhabricatorEditEngine.php | 25 +++++- ...catorEditEngineConfigurationEditEngine.php | 4 + ...torEditEngineConfigurationSearchEngine.php | 13 +-- ...atorEditEngineConfigurationTransaction.php | 43 ++++++++++ .../rsrc/css/phui/phui-two-column-view.css | 2 +- 27 files changed, 219 insertions(+), 55 deletions(-) diff --git a/resources/celerity/map.php b/resources/celerity/map.php index 65cda5a557..e8c312151e 100644 --- a/resources/celerity/map.php +++ b/resources/celerity/map.php @@ -156,7 +156,7 @@ return array( 'rsrc/css/phui/phui-status.css' => '37309046', 'rsrc/css/phui/phui-tag-view.css' => '6bbd83e2', 'rsrc/css/phui/phui-timeline-view.css' => '6e342216', - 'rsrc/css/phui/phui-two-column-view.css' => '9c43b599', + 'rsrc/css/phui/phui-two-column-view.css' => '691fec04', 'rsrc/css/phui/workboards/phui-workboard-color.css' => 'ac6fe6a7', 'rsrc/css/phui/workboards/phui-workboard.css' => 'e6d89647', 'rsrc/css/phui/workboards/phui-workcard.css' => '3646fb96', @@ -846,7 +846,7 @@ return array( 'phui-tag-view-css' => '6bbd83e2', 'phui-theme-css' => '027ba77e', 'phui-timeline-view-css' => '6e342216', - 'phui-two-column-view-css' => '9c43b599', + 'phui-two-column-view-css' => '691fec04', 'phui-workboard-color-css' => 'ac6fe6a7', 'phui-workboard-view-css' => 'e6d89647', 'phui-workcard-view-css' => '3646fb96', diff --git a/src/applications/almanac/editor/AlmanacBindingPropertyEditEngine.php b/src/applications/almanac/editor/AlmanacBindingPropertyEditEngine.php index ef51d755c5..a122681414 100644 --- a/src/applications/almanac/editor/AlmanacBindingPropertyEditEngine.php +++ b/src/applications/almanac/editor/AlmanacBindingPropertyEditEngine.php @@ -13,4 +13,8 @@ final class AlmanacBindingPropertyEditEngine return $object->getURI(); } + protected function getObjectName() { + return pht('Property'); + } + } diff --git a/src/applications/almanac/editor/AlmanacDeviceEditEngine.php b/src/applications/almanac/editor/AlmanacDeviceEditEngine.php index f8ace15caf..1d325e403b 100644 --- a/src/applications/almanac/editor/AlmanacDeviceEditEngine.php +++ b/src/applications/almanac/editor/AlmanacDeviceEditEngine.php @@ -53,6 +53,10 @@ final class AlmanacDeviceEditEngine return pht('Create Device'); } + protected function getObjectName() { + return pht('Device'); + } + protected function getEditorURI() { return '/almanac/device/edit/'; } diff --git a/src/applications/almanac/editor/AlmanacDevicePropertyEditEngine.php b/src/applications/almanac/editor/AlmanacDevicePropertyEditEngine.php index 9f10219591..122d0decd7 100644 --- a/src/applications/almanac/editor/AlmanacDevicePropertyEditEngine.php +++ b/src/applications/almanac/editor/AlmanacDevicePropertyEditEngine.php @@ -13,4 +13,8 @@ final class AlmanacDevicePropertyEditEngine return $object->getURI(); } + protected function getObjectName() { + return pht('Property'); + } + } diff --git a/src/applications/almanac/editor/AlmanacNamespaceEditEngine.php b/src/applications/almanac/editor/AlmanacNamespaceEditEngine.php index 0aaba76d3c..3b8c4ba2a6 100644 --- a/src/applications/almanac/editor/AlmanacNamespaceEditEngine.php +++ b/src/applications/almanac/editor/AlmanacNamespaceEditEngine.php @@ -53,6 +53,10 @@ final class AlmanacNamespaceEditEngine return pht('Create Namespace'); } + protected function getObjectName() { + return pht('Namespace'); + } + protected function getEditorURI() { return '/almanac/namespace/edit/'; } diff --git a/src/applications/almanac/editor/AlmanacNetworkEditEngine.php b/src/applications/almanac/editor/AlmanacNetworkEditEngine.php index a99079ff11..e474e81291 100644 --- a/src/applications/almanac/editor/AlmanacNetworkEditEngine.php +++ b/src/applications/almanac/editor/AlmanacNetworkEditEngine.php @@ -53,6 +53,10 @@ final class AlmanacNetworkEditEngine return pht('Create Network'); } + protected function getObjectName() { + return pht('Network'); + } + protected function getEditorURI() { return '/almanac/network/edit/'; } diff --git a/src/applications/almanac/editor/AlmanacServiceEditEngine.php b/src/applications/almanac/editor/AlmanacServiceEditEngine.php index 00e4e076de..e64cfce3a2 100644 --- a/src/applications/almanac/editor/AlmanacServiceEditEngine.php +++ b/src/applications/almanac/editor/AlmanacServiceEditEngine.php @@ -65,6 +65,10 @@ final class AlmanacServiceEditEngine return pht('Create Service'); } + protected function getObjectName() { + return pht('Service'); + } + protected function getEditorURI() { return '/almanac/service/edit/'; } diff --git a/src/applications/almanac/editor/AlmanacServicePropertyEditEngine.php b/src/applications/almanac/editor/AlmanacServicePropertyEditEngine.php index a56a10d575..505f89d36e 100644 --- a/src/applications/almanac/editor/AlmanacServicePropertyEditEngine.php +++ b/src/applications/almanac/editor/AlmanacServicePropertyEditEngine.php @@ -13,4 +13,8 @@ final class AlmanacServicePropertyEditEngine return $object->getURI(); } + protected function getObjectName() { + return pht('Property'); + } + } diff --git a/src/applications/badges/editor/PhabricatorBadgesEditEngine.php b/src/applications/badges/editor/PhabricatorBadgesEditEngine.php index 49a8e85022..70cdd08d39 100644 --- a/src/applications/badges/editor/PhabricatorBadgesEditEngine.php +++ b/src/applications/badges/editor/PhabricatorBadgesEditEngine.php @@ -34,7 +34,7 @@ final class PhabricatorBadgesEditEngine } protected function getObjectEditTitleText($object) { - return pht('Edit %s', $object->getName()); + return pht('Edit Badge: %s', $object->getName()); } protected function getObjectEditShortText($object) { @@ -45,6 +45,10 @@ final class PhabricatorBadgesEditEngine return pht('Create Badge'); } + protected function getObjectName() { + return pht('Badge'); + } + protected function getCommentViewHeaderText($object) { return pht('Add Comment'); } diff --git a/src/applications/drydock/editor/DrydockBlueprintEditEngine.php b/src/applications/drydock/editor/DrydockBlueprintEditEngine.php index bec86e5d4c..06117272a9 100644 --- a/src/applications/drydock/editor/DrydockBlueprintEditEngine.php +++ b/src/applications/drydock/editor/DrydockBlueprintEditEngine.php @@ -75,6 +75,10 @@ final class DrydockBlueprintEditEngine return pht('Create Blueprint'); } + protected function getObjectName() { + return pht('Blueprint'); + } + protected function getEditorURI() { return '/drydock/blueprint/edit/'; } diff --git a/src/applications/harbormaster/editor/HarbormasterBuildPlanEditEngine.php b/src/applications/harbormaster/editor/HarbormasterBuildPlanEditEngine.php index 342156c101..11837051c3 100644 --- a/src/applications/harbormaster/editor/HarbormasterBuildPlanEditEngine.php +++ b/src/applications/harbormaster/editor/HarbormasterBuildPlanEditEngine.php @@ -54,6 +54,10 @@ final class HarbormasterBuildPlanEditEngine return pht('Create Build Plan'); } + protected function getObjectName() { + return pht('Build Plan'); + } + protected function getEditorURI() { return '/harbormaster/plan/edit/'; } diff --git a/src/applications/maniphest/editor/ManiphestEditEngine.php b/src/applications/maniphest/editor/ManiphestEditEngine.php index fe9b96f25b..273c0c5472 100644 --- a/src/applications/maniphest/editor/ManiphestEditEngine.php +++ b/src/applications/maniphest/editor/ManiphestEditEngine.php @@ -34,7 +34,7 @@ final class ManiphestEditEngine } protected function getObjectEditTitleText($object) { - return pht('Edit %s %s', $object->getMonogram(), $object->getTitle()); + return pht('Edit Task: %s', $object->getTitle()); } protected function getObjectEditShortText($object) { @@ -45,6 +45,10 @@ final class ManiphestEditEngine return pht('Create Task'); } + protected function getObjectName() { + return pht('Task'); + } + protected function getEditorURI() { return $this->getApplication()->getApplicationURI('task/edit/'); } diff --git a/src/applications/nuance/editor/NuanceQueueEditEngine.php b/src/applications/nuance/editor/NuanceQueueEditEngine.php index 8e4de2611f..049916adbe 100644 --- a/src/applications/nuance/editor/NuanceQueueEditEngine.php +++ b/src/applications/nuance/editor/NuanceQueueEditEngine.php @@ -53,6 +53,10 @@ final class NuanceQueueEditEngine return pht('Create Queue'); } + protected function getObjectName() { + return pht('Queue'); + } + protected function getEditorURI() { return '/nuance/queue/edit/'; } diff --git a/src/applications/nuance/editor/NuanceSourceEditEngine.php b/src/applications/nuance/editor/NuanceSourceEditEngine.php index a01a21c20b..18d27863ac 100644 --- a/src/applications/nuance/editor/NuanceSourceEditEngine.php +++ b/src/applications/nuance/editor/NuanceSourceEditEngine.php @@ -74,6 +74,10 @@ final class NuanceSourceEditEngine return pht('Create Source'); } + protected function getObjectName() { + return pht('Source'); + } + protected function getEditorURI() { return '/nuance/source/edit/'; } diff --git a/src/applications/owners/editor/PhabricatorOwnersPackageEditEngine.php b/src/applications/owners/editor/PhabricatorOwnersPackageEditEngine.php index 62119e6dd6..fc97be6fce 100644 --- a/src/applications/owners/editor/PhabricatorOwnersPackageEditEngine.php +++ b/src/applications/owners/editor/PhabricatorOwnersPackageEditEngine.php @@ -35,7 +35,7 @@ final class PhabricatorOwnersPackageEditEngine } protected function getObjectEditTitleText($object) { - return pht('Edit Package %s', $object->getName()); + return pht('Edit Package: %s', $object->getName()); } protected function getObjectEditShortText($object) { @@ -46,6 +46,10 @@ final class PhabricatorOwnersPackageEditEngine return pht('Create Package'); } + protected function getObjectName() { + return pht('Package'); + } + protected function getObjectViewURI($object) { $id = $object->getID(); return "/owners/package/{$id}/"; diff --git a/src/applications/paste/editor/PhabricatorPasteEditEngine.php b/src/applications/paste/editor/PhabricatorPasteEditEngine.php index 4cc35ad6e3..7916279f69 100644 --- a/src/applications/paste/editor/PhabricatorPasteEditEngine.php +++ b/src/applications/paste/editor/PhabricatorPasteEditEngine.php @@ -46,6 +46,10 @@ final class PhabricatorPasteEditEngine return pht('Create Paste'); } + protected function getObjectName() { + return pht('Paste'); + } + protected function getCommentViewHeaderText($object) { return pht('Eat Paste'); } diff --git a/src/applications/phame/editor/PhameBlogEditEngine.php b/src/applications/phame/editor/PhameBlogEditEngine.php index 503a6bbd27..b9ee23a442 100644 --- a/src/applications/phame/editor/PhameBlogEditEngine.php +++ b/src/applications/phame/editor/PhameBlogEditEngine.php @@ -46,6 +46,10 @@ final class PhameBlogEditEngine return pht('Create Blog'); } + protected function getObjectName() { + return pht('Blog'); + } + protected function getObjectCreateCancelURI($object) { return $this->getApplication()->getApplicationURI('blog/'); } diff --git a/src/applications/phame/editor/PhamePostEditEngine.php b/src/applications/phame/editor/PhamePostEditEngine.php index 652922ea56..1c58722e2e 100644 --- a/src/applications/phame/editor/PhamePostEditEngine.php +++ b/src/applications/phame/editor/PhamePostEditEngine.php @@ -60,6 +60,10 @@ final class PhamePostEditEngine return pht('Create Post'); } + protected function getObjectName() { + return pht('Post'); + } + protected function getObjectViewURI($object) { return $object->getViewURI(); } diff --git a/src/applications/project/engine/PhabricatorProjectEditEngine.php b/src/applications/project/engine/PhabricatorProjectEditEngine.php index ee101cb2e4..760fad39d0 100644 --- a/src/applications/project/engine/PhabricatorProjectEditEngine.php +++ b/src/applications/project/engine/PhabricatorProjectEditEngine.php @@ -56,7 +56,7 @@ final class PhabricatorProjectEditEngine } protected function getObjectEditTitleText($object) { - return pht('Edit %s', $object->getName()); + return pht('Edit Project: %s', $object->getName()); } protected function getObjectEditShortText($object) { @@ -67,6 +67,10 @@ final class PhabricatorProjectEditEngine return pht('Create Project'); } + protected function getObjectName() { + return pht('Project'); + } + protected function getObjectViewURI($object) { if ($this->getIsCreate()) { return $object->getURI(); diff --git a/src/applications/search/editor/PhabricatorProfilePanelEditEngine.php b/src/applications/search/editor/PhabricatorProfilePanelEditEngine.php index 3a2f725719..e5689c8e68 100644 --- a/src/applications/search/editor/PhabricatorProfilePanelEditEngine.php +++ b/src/applications/search/editor/PhabricatorProfilePanelEditEngine.php @@ -108,6 +108,10 @@ final class PhabricatorProfilePanelEditEngine return pht('Edit Menu Item'); } + protected function getObjectName() { + return pht('Menu Item'); + } + protected function getObjectCreateCancelURI($object) { return $this->getPanelEngine()->getConfigureURI(); } diff --git a/src/applications/transactions/controller/PhabricatorEditEngineConfigurationDefaultsController.php b/src/applications/transactions/controller/PhabricatorEditEngineConfigurationDefaultsController.php index fa7f30c858..340431dd19 100644 --- a/src/applications/transactions/controller/PhabricatorEditEngineConfigurationDefaultsController.php +++ b/src/applications/transactions/controller/PhabricatorEditEngineConfigurationDefaultsController.php @@ -86,7 +86,7 @@ final class PhabricatorEditEngineConfigurationDefaultsController ->addCancelButton($cancel_uri)); $info = id(new PHUIInfoView()) - ->setSeverity(PHUIInfoView::SEVERITY_NOTICE) + ->setSeverity(PHUIInfoView::SEVERITY_WARNING) ->setErrors( array( pht('You are editing the default values for this form.'), @@ -94,18 +94,30 @@ final class PhabricatorEditEngineConfigurationDefaultsController $box = id(new PHUIObjectBoxView()) - ->setHeaderText($title) - ->setInfoView($info) + ->setHeaderText(pht('Form')) + ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) ->setForm($form); $crumbs = $this->buildApplicationCrumbs(); $crumbs->addTextCrumb(pht('Form %d', $config->getID()), $cancel_uri); $crumbs->addTextCrumb(pht('Edit Defaults')); + $crumbs->setBorder(true); + + $header = id(new PHUIHeaderView()) + ->setHeader(pht('Edit Form Defaults')) + ->setHeaderIcon('fa-pencil'); + + $view = id(new PHUITwoColumnView()) + ->setHeader($header) + ->setFooter(array( + $info, + $box, + )); return $this->newPage() ->setTitle($title) ->setCrumbs($crumbs) - ->appendChild($box); + ->appendChild($view); } } diff --git a/src/applications/transactions/controller/PhabricatorEditEngineConfigurationViewController.php b/src/applications/transactions/controller/PhabricatorEditEngineConfigurationViewController.php index 248abc79e5..23ccedd04d 100644 --- a/src/applications/transactions/controller/PhabricatorEditEngineConfigurationViewController.php +++ b/src/applications/transactions/controller/PhabricatorEditEngineConfigurationViewController.php @@ -17,27 +17,35 @@ final class PhabricatorEditEngineConfigurationViewController $is_concrete = (bool)$config->getID(); - $actions = $this->buildActionView($config); - - $properties = $this->buildPropertyView($config) - ->setActionList($actions); + $curtain = $this->buildCurtainView($config); + $properties = $this->buildPropertyView($config); $header = id(new PHUIHeaderView()) ->setUser($viewer) ->setPolicyObject($config) - ->setHeader(pht('Edit Form: %s', $config->getDisplayName())); + ->setHeader(pht('Edit Form: %s', $config->getDisplayName())) + ->setHeaderIcon('fa-pencil'); - $box = id(new PHUIObjectBoxView()) - ->setHeader($header) - ->addPropertyList($properties); + if ($config->getIsDisabled()) { + $name = pht('Disabled'); + $icon = 'fa-ban'; + $color = 'indigo'; + } else { + $name = pht('Enabled'); + $icon = 'fa-check'; + $color = 'green'; + } + $header->setStatus($icon, $color, $name); $field_list = $this->buildFieldList($config); - $crumbs = $this->buildApplicationCrumbs(); + $crumbs->setBorder(true); if ($is_concrete) { - $crumbs->addTextCrumb(pht('Form %d', $config->getID())); + $title = pht('Form %d', $config->getID()); + $crumbs->addTextCrumb($title); } else { + $title = pht('Builtin'); $crumbs->addTextCrumb(pht('Builtin')); } @@ -51,17 +59,21 @@ final class PhabricatorEditEngineConfigurationViewController $timeline = null; } + $view = id(new PHUITwoColumnView()) + ->setHeader($header) + ->setCurtain($curtain) + ->setMainColumn(array( + $field_list, + $timeline, + )); + return $this->newPage() + ->setTitle($title) ->setCrumbs($crumbs) - ->appendChild( - array( - $box, - $field_list, - $timeline, - )); + ->appendChild($view); } - private function buildActionView( + private function buildCurtainView( PhabricatorEditEngineConfiguration $config) { $viewer = $this->getViewer(); $engine = $config->getEngine(); @@ -72,9 +84,7 @@ final class PhabricatorEditEngineConfigurationViewController $config, PhabricatorPolicyCapability::CAN_EDIT); - $view = id(new PhabricatorActionListView()) - ->setUser($viewer); - + $curtain = $this->newCurtainView($config); $form_key = $config->getIdentifier(); $base_uri = "/transactions/editengine/{$engine_key}"; @@ -83,7 +93,7 @@ final class PhabricatorEditEngineConfigurationViewController if (!$is_concrete) { $save_uri = "{$base_uri}/save/{$form_key}/"; - $view->addAction( + $curtain->addAction( id(new PhabricatorActionView()) ->setName(pht('Make Editable')) ->setIcon('fa-pencil') @@ -94,7 +104,7 @@ final class PhabricatorEditEngineConfigurationViewController $can_edit = false; } else { $edit_uri = "{$base_uri}/edit/{$form_key}/"; - $view->addAction( + $curtain->addAction( id(new PhabricatorActionView()) ->setName(pht('Edit Form Configuration')) ->setIcon('fa-pencil') @@ -105,7 +115,7 @@ final class PhabricatorEditEngineConfigurationViewController $use_uri = $engine->getEditURI(null, "form/{$form_key}/"); - $view->addAction( + $curtain->addAction( id(new PhabricatorActionView()) ->setName(pht('Use Form')) ->setIcon('fa-th-list') @@ -113,7 +123,7 @@ final class PhabricatorEditEngineConfigurationViewController $defaults_uri = "{$base_uri}/defaults/{$form_key}/"; - $view->addAction( + $curtain->addAction( id(new PhabricatorActionView()) ->setName(pht('Change Default Values')) ->setIcon('fa-paint-brush') @@ -123,7 +133,7 @@ final class PhabricatorEditEngineConfigurationViewController $reorder_uri = "{$base_uri}/reorder/{$form_key}/"; - $view->addAction( + $curtain->addAction( id(new PhabricatorActionView()) ->setName(pht('Change Field Order')) ->setIcon('fa-sort-alpha-asc') @@ -133,7 +143,7 @@ final class PhabricatorEditEngineConfigurationViewController $lock_uri = "{$base_uri}/lock/{$form_key}/"; - $view->addAction( + $curtain->addAction( id(new PhabricatorActionView()) ->setName(pht('Lock / Hide Fields')) ->setIcon('fa-lock') @@ -151,7 +161,7 @@ final class PhabricatorEditEngineConfigurationViewController $disable_icon = 'fa-ban'; } - $view->addAction( + $curtain->addAction( id(new PhabricatorActionView()) ->setName($disable_name) ->setIcon($disable_icon) @@ -169,7 +179,7 @@ final class PhabricatorEditEngineConfigurationViewController $defaultcreate_icon = 'fa-plus'; } - $view->addAction( + $curtain->addAction( id(new PhabricatorActionView()) ->setName($defaultcreate_name) ->setIcon($defaultcreate_icon) @@ -187,7 +197,7 @@ final class PhabricatorEditEngineConfigurationViewController $isedit_uri = "{$base_uri}/defaultedit/{$form_key}/"; - $view->addAction( + $curtain->addAction( id(new PhabricatorActionView()) ->setName($isedit_name) ->setIcon($isedit_icon) @@ -195,7 +205,7 @@ final class PhabricatorEditEngineConfigurationViewController ->setWorkflow(true) ->setDisabled(!$can_edit)); - return $view; + return $curtain; } private function buildPropertyView( @@ -203,8 +213,7 @@ final class PhabricatorEditEngineConfigurationViewController $viewer = $this->getViewer(); $properties = id(new PHUIPropertyListView()) - ->setUser($viewer) - ->setObject($config); + ->setUser($viewer); return $properties; } @@ -226,7 +235,7 @@ final class PhabricatorEditEngineConfigurationViewController } $info = id(new PHUIInfoView()) - ->setSeverity(PHUIInfoView::SEVERITY_NOTICE) + ->setSeverity(PHUIInfoView::SEVERITY_WARNING) ->setErrors( array( pht('This is a preview of the current form configuration.'), @@ -234,10 +243,10 @@ final class PhabricatorEditEngineConfigurationViewController $box = id(new PHUIObjectBoxView()) ->setHeaderText(pht('Form Preview')) - ->setInfoView($info) + ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) ->setForm($form); - return $box; + return array($info, $box); } } diff --git a/src/applications/transactions/editengine/PhabricatorEditEngine.php b/src/applications/transactions/editengine/PhabricatorEditEngine.php index 3e6ff9c872..9655a83e65 100644 --- a/src/applications/transactions/editengine/PhabricatorEditEngine.php +++ b/src/applications/transactions/editengine/PhabricatorEditEngine.php @@ -188,6 +188,12 @@ abstract class PhabricatorEditEngine abstract protected function getObjectCreateShortText(); + /** + * @task text + */ + abstract protected function getObjectName(); + + /** * @task text */ @@ -988,8 +994,10 @@ abstract class PhabricatorEditEngine if ($this->getIsCreate()) { $header_text = $this->getFormHeaderText($object); + $header_icon = 'fa-plus-square'; } else { $header_text = $this->getObjectEditTitleText($object); + $header_icon = 'fa-pencil'; } $show_preview = !$request->isAjax(); @@ -1036,25 +1044,34 @@ abstract class PhabricatorEditEngine } $header = id(new PHUIHeaderView()) - ->setHeader($header_text); + ->setHeader($header_text) + ->setHeaderIcon($header_icon); if ($action_button) { $header->addActionLink($action_button); } $crumbs = $this->buildCrumbs($object, $final = true); + $crumbs->setBorder(true); $box = id(new PHUIObjectBoxView()) ->setUser($viewer) - ->setHeader($header) + ->setHeaderText($this->getObjectName()) ->setValidationException($validation_exception) + ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) ->appendChild($form); + $view = id(new PHUITwoColumnView()) + ->setHeader($header) + ->setFooter(array( + $box, + $previews, + )); + return $controller->newPage() ->setTitle($header_text) ->setCrumbs($crumbs) - ->appendChild($box) - ->appendChild($previews); + ->appendChild($view); } protected function newEditResponse( diff --git a/src/applications/transactions/editor/PhabricatorEditEngineConfigurationEditEngine.php b/src/applications/transactions/editor/PhabricatorEditEngineConfigurationEditEngine.php index 0305c19015..a9d96337ed 100644 --- a/src/applications/transactions/editor/PhabricatorEditEngineConfigurationEditEngine.php +++ b/src/applications/transactions/editor/PhabricatorEditEngineConfigurationEditEngine.php @@ -70,6 +70,10 @@ final class PhabricatorEditEngineConfigurationEditEngine return pht('Create Form'); } + protected function getObjectName() { + return pht('Form'); + } + protected function getObjectViewURI($object) { $id = $object->getID(); return $this->getURI("view/{$id}/"); diff --git a/src/applications/transactions/query/PhabricatorEditEngineConfigurationSearchEngine.php b/src/applications/transactions/query/PhabricatorEditEngineConfigurationSearchEngine.php index ca072f8172..52d48f528b 100644 --- a/src/applications/transactions/query/PhabricatorEditEngineConfigurationSearchEngine.php +++ b/src/applications/transactions/query/PhabricatorEditEngineConfigurationSearchEngine.php @@ -116,24 +116,27 @@ final class PhabricatorEditEngineConfigurationSearchEngine $id = $config->getID(); if ($id) { - $item->setObjectName(pht('Form %d', $id)); + $item->addIcon('fa-file-text-o bluegrey', pht('Form %d', $id)); $key = $id; } else { - $item->setObjectName(pht('Builtin')); + $item->addIcon('fa-file-text bluegrey', pht('Builtin')); $key = $config->getBuiltinKey(); } $item->setHref("/transactions/editengine/{$engine_key}/view/{$key}/"); if ($config->getIsDefault()) { - $item->addIcon('fa-plus', pht('Default')); + $item->addAttribute(pht('Default Create Form')); } if ($config->getIsEdit()) { - $item->addIcon('fa-pencil', pht('Edit Form')); + $item->addAttribute(pht('Edit Form')); } if ($config->getIsDisabled()) { - $item->addIcon('fa-ban', pht('Disabled')); + $item->setDisabled(true); + $item->setStatusIcon('fa-ban grey', pht('Disabled')); + } else { + $item->setStatusIcon('fa-file-text-o green', pht('Enabled')); } $list->addItem($item); diff --git a/src/applications/transactions/storage/PhabricatorEditEngineConfigurationTransaction.php b/src/applications/transactions/storage/PhabricatorEditEngineConfigurationTransaction.php index da5f0520f6..4bae34e5eb 100644 --- a/src/applications/transactions/storage/PhabricatorEditEngineConfigurationTransaction.php +++ b/src/applications/transactions/storage/PhabricatorEditEngineConfigurationTransaction.php @@ -104,4 +104,47 @@ final class PhabricatorEditEngineConfigurationTransaction return parent::getTitle(); } + public function getColor() { + $author_phid = $this->getAuthorPHID(); + + $old = $this->getOldValue(); + $new = $this->getNewValue(); + + $type = $this->getTransactionType(); + switch ($type) { + case PhabricatorTransactions::TYPE_CREATE: + return 'green'; + case self::TYPE_DISABLE: + if ($new) { + return 'indigo'; + } else { + return 'green'; + } + } + + return parent::getColor(); + } + + public function getIcon() { + $author_phid = $this->getAuthorPHID(); + + $old = $this->getOldValue(); + $new = $this->getNewValue(); + + $type = $this->getTransactionType(); + switch ($type) { + case PhabricatorTransactions::TYPE_CREATE: + return 'fa-plus'; + case self::TYPE_DISABLE: + if ($new) { + return 'fa-ban'; + } else { + return 'fa-check'; + } + } + + return parent::getIcon(); + } + + } diff --git a/webroot/rsrc/css/phui/phui-two-column-view.css b/webroot/rsrc/css/phui/phui-two-column-view.css index 3389d3e574..600945103d 100644 --- a/webroot/rsrc/css/phui/phui-two-column-view.css +++ b/webroot/rsrc/css/phui/phui-two-column-view.css @@ -188,7 +188,7 @@ /* Info View */ -.phui-two-column-view .phui-two-column-row .phui-info-view { +.phui-two-column-view .phui-info-view { margin: 0 0 20px 0; padding: 16px; } From e6d2e66ea250a78db5f056253dcba65240ba62e8 Mon Sep 17 00:00:00 2001 From: lkassianik Date: Sat, 26 Mar 2016 19:36:13 -0700 Subject: [PATCH 10/42] Adding basic transaction titles to awarding/revoking badges Summary: Ref T10677, awarding/revoking a badge should create timeline entries with titles that are more clear (excludes homepage feed stories) Test Plan: Award/revoke a badge to single or multiple users. See timeline entries that reflect those actions. Reviewers: epriestley, #blessed_reviewers Reviewed By: epriestley, #blessed_reviewers Subscribers: Korvin Maniphest Tasks: T10677 Differential Revision: https://secure.phabricator.com/D15533 --- .../storage/PhabricatorBadgesTransaction.php | 40 +++++++++++++++++++ .../PhabricatorUSEnglishTranslation.php | 14 +++++++ 2 files changed, 54 insertions(+) diff --git a/src/applications/badges/storage/PhabricatorBadgesTransaction.php b/src/applications/badges/storage/PhabricatorBadgesTransaction.php index f25c629c96..dc92d1fc8f 100644 --- a/src/applications/badges/storage/PhabricatorBadgesTransaction.php +++ b/src/applications/badges/storage/PhabricatorBadgesTransaction.php @@ -109,6 +109,26 @@ final class PhabricatorBadgesTransaction $qual_new); } break; + case self::TYPE_AWARD: + if (!is_array($new)) { + $new = array(); + } + $handles = $this->renderHandleList($new); + return pht( + '%s awarded this badge to %s recipient(s): %s.', + $this->renderHandleLink($author_phid), + new PhutilNumber(count($new)), + $handles); + case self::TYPE_REVOKE: + if (!is_array($new)) { + $new = array(); + } + $handles = $this->renderHandleList($new); + return pht( + '%s revoked this badge from %s recipient(s): %s.', + $this->renderHandleLink($author_phid), + new PhutilNumber(count($new)), + $handles); } return parent::getTitle(); @@ -223,4 +243,24 @@ final class PhabricatorBadgesTransaction $this->getOldValue(), $this->getNewValue()); } + + public function getRequiredHandlePHIDs() { + $phids = parent::getRequiredHandlePHIDs(); + + $type = $this->getTransactionType(); + switch ($type) { + case self::TYPE_AWARD: + case self::TYPE_REVOKE: + $new = $this->getNewValue(); + if (!is_array($new)) { + $new = array(); + } + foreach ($new as $phid) { + $phids[] = $phid; + } + break; + } + + return $phids; + } } diff --git a/src/infrastructure/internationalization/translation/PhabricatorUSEnglishTranslation.php b/src/infrastructure/internationalization/translation/PhabricatorUSEnglishTranslation.php index 93027ce5d6..54e69476d4 100644 --- a/src/infrastructure/internationalization/translation/PhabricatorUSEnglishTranslation.php +++ b/src/infrastructure/internationalization/translation/PhabricatorUSEnglishTranslation.php @@ -1528,6 +1528,20 @@ final class PhabricatorUSEnglishTranslation '%s removed watchers for %3$s: %4$s.', ), ), + + '%s awarded this badge to %s recipient(s): %s.' => array( + array( + '%s awarded this badge to recipient: %3$s.', + '%s awarded this badge to recipients: %3$s.', + ), + ), + + '%s revoked this badge from %s recipient(s): %s.' => array( + array( + '%s revoked this badge from recipient: %3$s.', + '%s revoked this badge from recipients: %3$s.', + ), + ), ); } From 3955ff719a3d82a840cb75055314819681a568bf Mon Sep 17 00:00:00 2001 From: lkassianik Date: Mon, 28 Mar 2016 10:21:20 -0700 Subject: [PATCH 11/42] Create feed transaction stories for awarding/revoking badges Summary: Ref T10677, Awarding/revoking badge should create a feed story on homepage with badge handle recipient handles Test Plan: Award/revoke badge, open Feed, should see story with badge link and recipient links. Reviewers: epriestley, #blessed_reviewers Reviewed By: epriestley, #blessed_reviewers Subscribers: Korvin Maniphest Tasks: T10677 Differential Revision: https://secure.phabricator.com/D15534 --- .../storage/PhabricatorBadgesTransaction.php | 22 +++++++++++++++++++ .../PhabricatorUSEnglishTranslation.php | 14 ++++++++++++ 2 files changed, 36 insertions(+) diff --git a/src/applications/badges/storage/PhabricatorBadgesTransaction.php b/src/applications/badges/storage/PhabricatorBadgesTransaction.php index dc92d1fc8f..c8da36eda4 100644 --- a/src/applications/badges/storage/PhabricatorBadgesTransaction.php +++ b/src/applications/badges/storage/PhabricatorBadgesTransaction.php @@ -191,6 +191,28 @@ final class PhabricatorBadgesTransaction $this->renderHandleLink($object_phid)); } break; + case self::TYPE_AWARD: + if (!is_array($new)) { + $new = array(); + } + $handles = $this->renderHandleList($new); + return pht( + '%s awarded %s to %s recipient(s): %s.', + $this->renderHandleLink($author_phid), + $this->renderHandleLink($object_phid), + new PhutilNumber(count($new)), + $handles); + case self::TYPE_REVOKE: + if (!is_array($new)) { + $new = array(); + } + $handles = $this->renderHandleList($new); + return pht( + '%s revoked %s from %s recipient(s): %s.', + $this->renderHandleLink($author_phid), + $this->renderHandleLink($object_phid), + new PhutilNumber(count($new)), + $handles); } return parent::getTitleForFeed(); diff --git a/src/infrastructure/internationalization/translation/PhabricatorUSEnglishTranslation.php b/src/infrastructure/internationalization/translation/PhabricatorUSEnglishTranslation.php index 54e69476d4..492d68dd1b 100644 --- a/src/infrastructure/internationalization/translation/PhabricatorUSEnglishTranslation.php +++ b/src/infrastructure/internationalization/translation/PhabricatorUSEnglishTranslation.php @@ -1542,6 +1542,20 @@ final class PhabricatorUSEnglishTranslation '%s revoked this badge from recipients: %3$s.', ), ), + + '%s awarded %s to %s recipient(s): %s.' => array( + array( + '%s awarded %s to recipient: %4$s.', + '%s awarded %s to recipients: %4$s.', + ), + ), + + '%s revoked %s from %s recipient(s): %s.' => array( + array( + '%s revoked %s from recipient: %4$s.', + '%s revoked %s from recipients: %4$s.', + ), + ), ); } From a4270e5413b41ff6658512db53d611e3e5d81fc0 Mon Sep 17 00:00:00 2001 From: lkassianik Date: Mon, 28 Mar 2016 10:29:25 -0700 Subject: [PATCH 12/42] Archiving badge needs meaningful Badge timeline event title Summary: Ref T10677, archiving/activating a badge should create non-generic timeline events. Test Plan: Archive/activate badge, view badge timeline, see story corresponding to archiving/activating actions. Reviewers: epriestley, #blessed_reviewers Reviewed By: epriestley, #blessed_reviewers Subscribers: Korvin Maniphest Tasks: T10677 Differential Revision: https://secure.phabricator.com/D15536 --- .../badges/storage/PhabricatorBadgesTransaction.php | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/applications/badges/storage/PhabricatorBadgesTransaction.php b/src/applications/badges/storage/PhabricatorBadgesTransaction.php index c8da36eda4..85c0bdce4a 100644 --- a/src/applications/badges/storage/PhabricatorBadgesTransaction.php +++ b/src/applications/badges/storage/PhabricatorBadgesTransaction.php @@ -73,6 +73,18 @@ final class PhabricatorBadgesTransaction $this->renderHandleLink($author_phid)); } break; + case self::TYPE_STATUS: + switch ($new) { + case PhabricatorBadgesBadge::STATUS_ACTIVE: + return pht( + '%s activated this badge.', + $this->renderHandleLink($author_phid)); + case PhabricatorBadgesBadge::STATUS_ARCHIVED: + return pht( + '%s archived this badge.', + $this->renderHandleLink($author_phid)); + } + break; case self::TYPE_ICON: if ($old === null) { return pht( From da1ebac8d8fa7cfd10cecc3d22836e23ba678e4c Mon Sep 17 00:00:00 2001 From: epriestley Date: Mon, 28 Mar 2016 10:54:13 -0700 Subject: [PATCH 13/42] Allow Nuance items to provide curtain panels, link to imported tasks, parse comments Summary: Ref T10537. - Let nuance items render custom curtain panels. - Add a custom panel linking to the imported task, if one exists. - Actually extract comments properly. Test Plan: Unit tests, plus: {F1193800} {F1193801} Reviewers: chad Reviewed By: chad Maniphest Tasks: T10537 Differential Revision: https://secure.phabricator.com/D15537 --- .../controller/NuanceItemViewController.php | 4 ++++ .../nuance/github/NuanceGitHubRawEvent.php | 8 ++++++- .../NuanceGitHubRawEventTestCase.php | 1 + .../IssueCommentEvent.created.pull.txt | 3 ++- .../IssueCommentEvent.created.txt | 3 ++- .../nuance/item/NuanceGitHubEventItemType.php | 23 +++++++++++++++++++ .../nuance/item/NuanceItemType.php | 8 +++++++ 7 files changed, 47 insertions(+), 3 deletions(-) diff --git a/src/applications/nuance/controller/NuanceItemViewController.php b/src/applications/nuance/controller/NuanceItemViewController.php index 091ade2d6b..7ef5d06682 100644 --- a/src/applications/nuance/controller/NuanceItemViewController.php +++ b/src/applications/nuance/controller/NuanceItemViewController.php @@ -76,6 +76,10 @@ final class NuanceItemViewController extends NuanceController { $curtain->addAction($action); } + foreach ($impl->getItemCurtainPanels($item) as $panel) { + $curtain->addPanel($panel); + } + return $curtain; } diff --git a/src/applications/nuance/github/NuanceGitHubRawEvent.php b/src/applications/nuance/github/NuanceGitHubRawEvent.php index 1283fb43b7..4da2bb8e46 100644 --- a/src/applications/nuance/github/NuanceGitHubRawEvent.php +++ b/src/applications/nuance/github/NuanceGitHubRawEvent.php @@ -91,7 +91,13 @@ final class NuanceGitHubRawEvent extends Phobject { } public function getComment() { - return 'TODO: Actually extract comment text.'; + if (!$this->isIssueEvent() && !$this->isPullRequestEvent()) { + return null; + } + + $raw = $this->raw; + + return idxv($raw, array('payload', 'comment', 'body')); } public function getURI() { diff --git a/src/applications/nuance/github/__tests__/NuanceGitHubRawEventTestCase.php b/src/applications/nuance/github/__tests__/NuanceGitHubRawEventTestCase.php index f5e2119141..5bdc3f34aa 100644 --- a/src/applications/nuance/github/__tests__/NuanceGitHubRawEventTestCase.php +++ b/src/applications/nuance/github/__tests__/NuanceGitHubRawEventTestCase.php @@ -51,6 +51,7 @@ final class NuanceGitHubRawEventTestCase 'id' => $event->getID(), 'uri' => $event->getURI(), 'title.full' => $event->getEventFullTitle(), + 'comment' => $event->getComment(), ); // Only verify the keys which are actually present in the test. This diff --git a/src/applications/nuance/github/__tests__/repositoryevents/IssueCommentEvent.created.pull.txt b/src/applications/nuance/github/__tests__/repositoryevents/IssueCommentEvent.created.pull.txt index 71abbceac4..1991bb568e 100644 --- a/src/applications/nuance/github/__tests__/repositoryevents/IssueCommentEvent.created.pull.txt +++ b/src/applications/nuance/github/__tests__/repositoryevents/IssueCommentEvent.created.pull.txt @@ -160,5 +160,6 @@ "pull.number": 2, "id": 3740938746, "uri": "https://github.com/epriestley/poems/pull/2#issuecomment-194282800", - "title.full": "GitHub epriestley/poems Pull Request #2 (Comment)" + "title.full": "GitHub epriestley/poems Pull Request #2 (Comment)", + "comment": "wub wub" } diff --git a/src/applications/nuance/github/__tests__/repositoryevents/IssueCommentEvent.created.txt b/src/applications/nuance/github/__tests__/repositoryevents/IssueCommentEvent.created.txt index a1ca094045..d22fd86e25 100644 --- a/src/applications/nuance/github/__tests__/repositoryevents/IssueCommentEvent.created.txt +++ b/src/applications/nuance/github/__tests__/repositoryevents/IssueCommentEvent.created.txt @@ -97,5 +97,6 @@ "issue.number": 1, "id": 3733510485, "uri": "https://github.com/epriestley/poems/issues/1#issuecomment-193528669", - "title.full": "GitHub epriestley/poems Issue #1 (Comment)" + "title.full": "GitHub epriestley/poems Issue #1 (Comment)", + "comment": "comment on issue" } diff --git a/src/applications/nuance/item/NuanceGitHubEventItemType.php b/src/applications/nuance/item/NuanceGitHubEventItemType.php index 75f44e8964..617d75e493 100644 --- a/src/applications/nuance/item/NuanceGitHubEventItemType.php +++ b/src/applications/nuance/item/NuanceGitHubEventItemType.php @@ -154,6 +154,29 @@ final class NuanceGitHubEventItemType return $actions; } + public function getItemCurtainPanels(NuanceItem $item) { + $viewer = $this->getViewer(); + + $panels = array(); + + $xobj = $this->getExternalObject($item); + if ($xobj) { + $xobj_phid = $xobj->getPHID(); + + $task = id(new ManiphestTaskQuery()) + ->setViewer($viewer) + ->withBridgedObjectPHIDs(array($xobj_phid)) + ->executeOne(); + if ($task) { + $panels[] = $this->newCurtainPanel($item) + ->setHeaderText(pht('Imported As')) + ->appendChild($viewer->renderHandle($task->getPHID())); + } + } + + return $panels; + } + protected function handleAction(NuanceItem $item, $action) { $viewer = $this->getViewer(); $controller = $this->getController(); diff --git a/src/applications/nuance/item/NuanceItemType.php b/src/applications/nuance/item/NuanceItemType.php index d4187bf418..a1186c6ddd 100644 --- a/src/applications/nuance/item/NuanceItemType.php +++ b/src/applications/nuance/item/NuanceItemType.php @@ -44,6 +44,10 @@ abstract class NuanceItemType return array(); } + public function getItemCurtainPanels(NuanceItem $item) { + return array(); + } + abstract public function getItemTypeDisplayName(); abstract public function getItemDisplayName(NuanceItem $item); @@ -82,6 +86,10 @@ abstract class NuanceItemType ->setHref($action_uri); } + final protected function newCurtainPanel(NuanceItem $item) { + return id(new PHUICurtainPanelView()); + } + final public function buildActionResponse(NuanceItem $item, $action) { $response = $this->handleAction($item, $action); From bf3879b1c72fa77abefd9e0707a0b5c414b0271c Mon Sep 17 00:00:00 2001 From: epriestley Date: Mon, 28 Mar 2016 10:20:43 -0700 Subject: [PATCH 14/42] Fully fix a bad rule object aliasing issue custom remarkup rules Summary: Fixes T10234. This is a more thorough fix. Root issue is that some time around D13589, we started hitting an object cache for `loadCustomInlineRules()`, but didn't adjust the code to account for that. So if a page created multiple similar engines, we'd return the same `$rule` object for multiple engines, call `setEngine()` on it with different engines, and then possibly try to render using an already-expired engine the second time through. Instead, create a separate `$rule` object for each separate `$engine`. Test Plan: Repro is something like this: - Create a custominlinerule which uses an engine. - Purge the remarkup cache. - Load a page which uses the rule in two engines (e.g., in a revision description, and also in an inline comment). - Before change: second one could fatal. After change: clean load. Reviewers: thoughtpolice, chad Reviewed By: thoughtpolice, chad Subscribers: thoughtpolice, eadler Maniphest Tasks: T10234 Differential Revision: https://secure.phabricator.com/D15535 --- src/infrastructure/markup/PhabricatorMarkupEngine.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/infrastructure/markup/PhabricatorMarkupEngine.php b/src/infrastructure/markup/PhabricatorMarkupEngine.php index f32971646a..38eb0c500e 100644 --- a/src/infrastructure/markup/PhabricatorMarkupEngine.php +++ b/src/infrastructure/markup/PhabricatorMarkupEngine.php @@ -517,7 +517,7 @@ final class PhabricatorMarkupEngine extends Phobject { $rules[] = new PhutilRemarkupHighlightRule(); foreach (self::loadCustomInlineRules() as $rule) { - $rules[] = $rule; + $rules[] = clone $rule; } $blocks = array(); From 878b9413091c711c611ffc3f3d0ff3df0a444688 Mon Sep 17 00:00:00 2001 From: lkassianik Date: Mon, 28 Mar 2016 11:10:27 -0700 Subject: [PATCH 15/42] Show "no badges" text in people profiles with archived badges only Summary: Fixes T10670, for users with exclusively archived badges, user profile should show "no badges" message instead of blank box Test Plan: Award badge to user with no badges, archive badge, user profile should show "no badges" message under badges. Reviewers: epriestley, #blessed_reviewers Reviewed By: epriestley, #blessed_reviewers Subscribers: Korvin Maniphest Tasks: T10670 Differential Revision: https://secure.phabricator.com/D15538 --- .../controller/PhabricatorPeopleProfileViewController.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/applications/people/controller/PhabricatorPeopleProfileViewController.php b/src/applications/people/controller/PhabricatorPeopleProfileViewController.php index d8bb1d4f4d..213fc94b0e 100644 --- a/src/applications/people/controller/PhabricatorPeopleProfileViewController.php +++ b/src/applications/people/controller/PhabricatorPeopleProfileViewController.php @@ -188,7 +188,11 @@ final class PhabricatorPeopleProfileViewController ->withPHIDs($badge_phids) ->withStatuses(array(PhabricatorBadgesBadge::STATUS_ACTIVE)) ->execute(); + } else { + $badges = array(); + } + if (count($badges)) { $flex = new PHUIBadgeBoxView(); foreach ($badges as $badge) { $item = id(new PHUIBadgeView()) @@ -198,7 +202,6 @@ final class PhabricatorPeopleProfileViewController ->setQuality($badge->getQuality()); $flex->addItem($item); } - } else { $error = id(new PHUIBoxView()) ->addClass('mlb') From f9306c2e58db5d3c8074cee093ac8c59457d14b9 Mon Sep 17 00:00:00 2001 From: epriestley Date: Mon, 28 Mar 2016 11:18:39 -0700 Subject: [PATCH 16/42] Add a Nuance content source, and make use of it Summary: Ref T10537. Add a new content source for Nuance. Prepare for better author attribution. Test Plan: {F1194038} Reviewers: chad Reviewed By: chad Maniphest Tasks: T10537 Differential Revision: https://secure.phabricator.com/D15539 --- src/__phutil_library_map__.php | 2 ++ .../contentsource/NuanceContentSource.php | 16 ++++++++++++++++ .../nuance/item/NuanceGitHubEventItemType.php | 19 ++++++++++--------- .../nuance/item/NuanceItemType.php | 15 +++++++++++++++ 4 files changed, 43 insertions(+), 9 deletions(-) create mode 100644 src/applications/nuance/contentsource/NuanceContentSource.php diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php index 75541320c0..9a2a1a7e19 100644 --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -1426,6 +1426,7 @@ phutil_register_library_map(array( 'MultimeterViewer' => 'applications/multimeter/storage/MultimeterViewer.php', 'NuanceConduitAPIMethod' => 'applications/nuance/conduit/NuanceConduitAPIMethod.php', 'NuanceConsoleController' => 'applications/nuance/controller/NuanceConsoleController.php', + 'NuanceContentSource' => 'applications/nuance/contentsource/NuanceContentSource.php', 'NuanceController' => 'applications/nuance/controller/NuanceController.php', 'NuanceDAO' => 'applications/nuance/storage/NuanceDAO.php', 'NuanceGitHubEventItemType' => 'applications/nuance/item/NuanceGitHubEventItemType.php', @@ -5726,6 +5727,7 @@ phutil_register_library_map(array( 'MultimeterViewer' => 'MultimeterDimension', 'NuanceConduitAPIMethod' => 'ConduitAPIMethod', 'NuanceConsoleController' => 'NuanceController', + 'NuanceContentSource' => 'PhabricatorContentSource', 'NuanceController' => 'PhabricatorController', 'NuanceDAO' => 'PhabricatorLiskDAO', 'NuanceGitHubEventItemType' => 'NuanceItemType', diff --git a/src/applications/nuance/contentsource/NuanceContentSource.php b/src/applications/nuance/contentsource/NuanceContentSource.php new file mode 100644 index 0000000000..030db940a6 --- /dev/null +++ b/src/applications/nuance/contentsource/NuanceContentSource.php @@ -0,0 +1,16 @@ +getPHID(); + $acting_as_phid = $this->getActingAsPHID($item); $xactions = array(); @@ -307,7 +307,7 @@ final class NuanceGitHubEventItemType ->executeOne(); if (!$task) { $task = ManiphestTask::initializeNewTask($viewer) - ->setAuthorPHID($nuance_phid) + ->setAuthorPHID($acting_as_phid) ->setBridgedObjectPHID($xobj_phid); $title = $xobj->getProperty('task.title'); @@ -344,16 +344,12 @@ final class NuanceGitHubEventItemType ->setContent($comment)); } - // TODO: Preserve the item's original source. - $source = PhabricatorContentSource::newForSource( - PhabricatorDaemonContentSource::SOURCECONST); - - // TODO: This should really be the external source. - $acting_phid = $nuance_phid; + $agent_phid = $command->getAuthorPHID(); + $source = $this->newContentSource($item, $agent_phid); $editor = id(new ManiphestTransactionEditor()) ->setActor($viewer) - ->setActingAsPHID($acting_phid) + ->setActingAsPHID($acting_as_phid) ->setContentSource($source) ->setContinueOnNoEffect(true) ->setContinueOnMissingFields(true); @@ -366,5 +362,10 @@ final class NuanceGitHubEventItemType ); } + protected function getActingAsPHID(NuanceItem $item) { + // TODO: This should be an external account PHID representing the original + // GitHub user. + return parent::getActingAsPHID($item); + } } diff --git a/src/applications/nuance/item/NuanceItemType.php b/src/applications/nuance/item/NuanceItemType.php index a1186c6ddd..74555494d0 100644 --- a/src/applications/nuance/item/NuanceItemType.php +++ b/src/applications/nuance/item/NuanceItemType.php @@ -144,4 +144,19 @@ abstract class NuanceItemType return null; } + final protected function newContentSource( + NuanceItem $item, + $agent_phid) { + return PhabricatorContentSource::newForSource( + NuanceContentSource::SOURCECONST, + array( + 'itemPHID' => $item->getPHID(), + 'agentPHID' => $agent_phid, + )); + } + + protected function getActingAsPHID(NuanceItem $item) { + return id(new PhabricatorNuanceApplication())->getPHID(); + } + } From e5427a95211f35cd362ea5be999636f958325e84 Mon Sep 17 00:00:00 2001 From: epriestley Date: Mon, 28 Mar 2016 11:43:44 -0700 Subject: [PATCH 17/42] Extract GitHub actor IDs from GitHub events Summary: Ref T10538. This probably gets push events where GitHub does not recognize the author wrong, but I don't have any of those yet. Test Plan: Added and ran unit tests. Reviewers: chad Reviewed By: chad Maniphest Tasks: T10538 Differential Revision: https://secure.phabricator.com/D15540 --- src/applications/nuance/github/NuanceGitHubRawEvent.php | 5 +++++ .../nuance/github/__tests__/NuanceGitHubRawEventTestCase.php | 1 + .../nuance/github/__tests__/issueevents/assigned.txt | 3 ++- .../nuance/github/__tests__/issueevents/closed.txt | 3 ++- .../nuance/github/__tests__/issueevents/demilestoned.txt | 3 ++- .../nuance/github/__tests__/issueevents/labeled.txt | 3 ++- .../nuance/github/__tests__/issueevents/milestoned.txt | 3 ++- .../nuance/github/__tests__/issueevents/renamed.txt | 3 ++- .../nuance/github/__tests__/issueevents/reopened.txt | 3 ++- .../nuance/github/__tests__/issueevents/unassigned.txt | 3 ++- .../nuance/github/__tests__/issueevents/unlabeled.txt | 3 ++- .../nuance/github/__tests__/issueevents/unlocked.txt | 3 ++- .../github/__tests__/repositoryevents/CreateEvent.tag.txt | 3 ++- .../repositoryevents/IssueCommentEvent.created.pull.txt | 3 ++- .../__tests__/repositoryevents/IssueCommentEvent.created.txt | 3 ++- .../github/__tests__/repositoryevents/IssuesEvent.closed.txt | 3 ++- .../github/__tests__/repositoryevents/IssuesEvent.opened.txt | 3 ++- .../__tests__/repositoryevents/IssuesEvent.reopened.txt | 3 ++- .../__tests__/repositoryevents/PullRequestEvent.opened.txt | 3 ++- .../nuance/github/__tests__/repositoryevents/PushEvent.txt | 3 ++- .../github/__tests__/repositoryevents/WatchEvent.started.txt | 3 ++- 21 files changed, 44 insertions(+), 19 deletions(-) diff --git a/src/applications/nuance/github/NuanceGitHubRawEvent.php b/src/applications/nuance/github/NuanceGitHubRawEvent.php index 4da2bb8e46..b28a9222dc 100644 --- a/src/applications/nuance/github/NuanceGitHubRawEvent.php +++ b/src/applications/nuance/github/NuanceGitHubRawEvent.php @@ -236,6 +236,11 @@ final class NuanceGitHubRawEvent extends Phobject { $title); } + public function getActorGitHubUserID() { + $raw = $this->raw; + return (int)idxv($raw, array('actor', 'id')); + } + private function getTargetObjectName() { if ($this->isPullRequestEvent()) { $number = $this->getRawIssueNumber(); diff --git a/src/applications/nuance/github/__tests__/NuanceGitHubRawEventTestCase.php b/src/applications/nuance/github/__tests__/NuanceGitHubRawEventTestCase.php index 5bdc3f34aa..29b9e3c0a9 100644 --- a/src/applications/nuance/github/__tests__/NuanceGitHubRawEventTestCase.php +++ b/src/applications/nuance/github/__tests__/NuanceGitHubRawEventTestCase.php @@ -52,6 +52,7 @@ final class NuanceGitHubRawEventTestCase 'uri' => $event->getURI(), 'title.full' => $event->getEventFullTitle(), 'comment' => $event->getComment(), + 'actor.id' => $event->getActorGitHubUserID(), ); // Only verify the keys which are actually present in the test. This diff --git a/src/applications/nuance/github/__tests__/issueevents/assigned.txt b/src/applications/nuance/github/__tests__/issueevents/assigned.txt index a126186b19..8847a5d860 100644 --- a/src/applications/nuance/github/__tests__/issueevents/assigned.txt +++ b/src/applications/nuance/github/__tests__/issueevents/assigned.txt @@ -113,5 +113,6 @@ "issue.number": 1, "id": 583217900, "uri": "https://github.com/epriestley/poems/issues/1#event-583217900", - "title.full": "GitHub epriestley/poems Issue #1 (Assigned: epriestley)" + "title.full": "GitHub epriestley/poems Issue #1 (Assigned: epriestley)", + "actor.id": 102631 } diff --git a/src/applications/nuance/github/__tests__/issueevents/closed.txt b/src/applications/nuance/github/__tests__/issueevents/closed.txt index 6428fc6bcb..db66ff25bd 100644 --- a/src/applications/nuance/github/__tests__/issueevents/closed.txt +++ b/src/applications/nuance/github/__tests__/issueevents/closed.txt @@ -75,5 +75,6 @@ "issue.number": 1, "id": 583218864, "uri": "https://github.com/epriestley/poems/issues/1#event-583218864", - "title.full": "GitHub epriestley/poems Issue #1 (Closed)" + "title.full": "GitHub epriestley/poems Issue #1 (Closed)", + "actor.id": 102631 } diff --git a/src/applications/nuance/github/__tests__/issueevents/demilestoned.txt b/src/applications/nuance/github/__tests__/issueevents/demilestoned.txt index 5c32ec6c6c..b144a321de 100644 --- a/src/applications/nuance/github/__tests__/issueevents/demilestoned.txt +++ b/src/applications/nuance/github/__tests__/issueevents/demilestoned.txt @@ -78,5 +78,6 @@ "issue.number": 1, "id": 583218613, "uri": "https://github.com/epriestley/poems/issues/1#event-583218613", - "title.full": "GitHub epriestley/poems Issue #1 (Removed Milestone: b)" + "title.full": "GitHub epriestley/poems Issue #1 (Removed Milestone: b)", + "actor.id": 102631 } diff --git a/src/applications/nuance/github/__tests__/issueevents/labeled.txt b/src/applications/nuance/github/__tests__/issueevents/labeled.txt index bb88a13b9a..b2458ce0a4 100644 --- a/src/applications/nuance/github/__tests__/issueevents/labeled.txt +++ b/src/applications/nuance/github/__tests__/issueevents/labeled.txt @@ -79,5 +79,6 @@ "issue.number": 1, "id": 583217784, "uri": "https://github.com/epriestley/poems/issues/1#event-583217784", - "title.full": "GitHub epriestley/poems Issue #1 (Added Label: bug)" + "title.full": "GitHub epriestley/poems Issue #1 (Added Label: bug)", + "actor.id": 102631 } diff --git a/src/applications/nuance/github/__tests__/issueevents/milestoned.txt b/src/applications/nuance/github/__tests__/issueevents/milestoned.txt index 3e5a6a4590..ad56c4020a 100644 --- a/src/applications/nuance/github/__tests__/issueevents/milestoned.txt +++ b/src/applications/nuance/github/__tests__/issueevents/milestoned.txt @@ -78,5 +78,6 @@ "issue.number": 1, "id": 583217866, "uri": "https://github.com/epriestley/poems/issues/1#event-583217866", - "title.full": "GitHub epriestley/poems Issue #1 (Added Milestone: b)" + "title.full": "GitHub epriestley/poems Issue #1 (Added Milestone: b)", + "actor.id": 102631 } diff --git a/src/applications/nuance/github/__tests__/issueevents/renamed.txt b/src/applications/nuance/github/__tests__/issueevents/renamed.txt index 08a3c0c448..ecf6e4f465 100644 --- a/src/applications/nuance/github/__tests__/issueevents/renamed.txt +++ b/src/applications/nuance/github/__tests__/issueevents/renamed.txt @@ -79,5 +79,6 @@ "issue.number": 1, "id": 583218162, "uri": "https://github.com/epriestley/poems/issues/1#event-583218162", - "title.full": "GitHub epriestley/poems Issue #1 (Renamed)" + "title.full": "GitHub epriestley/poems Issue #1 (Renamed)", + "actor.id": 102631 } diff --git a/src/applications/nuance/github/__tests__/issueevents/reopened.txt b/src/applications/nuance/github/__tests__/issueevents/reopened.txt index 26d5b3ec75..be66183d17 100644 --- a/src/applications/nuance/github/__tests__/issueevents/reopened.txt +++ b/src/applications/nuance/github/__tests__/issueevents/reopened.txt @@ -75,5 +75,6 @@ "issue.number": 1, "id": 583218814, "uri": "https://github.com/epriestley/poems/issues/1#event-583218814", - "title.full": "GitHub epriestley/poems Issue #1 (Reopened)" + "title.full": "GitHub epriestley/poems Issue #1 (Reopened)", + "actor.id": 102631 } diff --git a/src/applications/nuance/github/__tests__/issueevents/unassigned.txt b/src/applications/nuance/github/__tests__/issueevents/unassigned.txt index 086401afa7..2086e277ec 100644 --- a/src/applications/nuance/github/__tests__/issueevents/unassigned.txt +++ b/src/applications/nuance/github/__tests__/issueevents/unassigned.txt @@ -113,5 +113,6 @@ "issue.number": 1, "id": 583218511, "uri": "https://github.com/epriestley/poems/issues/1#event-583218511", - "title.full": "GitHub epriestley/poems Issue #1 (Unassigned: epriestley)" + "title.full": "GitHub epriestley/poems Issue #1 (Unassigned: epriestley)", + "actor.id": 102631 } diff --git a/src/applications/nuance/github/__tests__/issueevents/unlabeled.txt b/src/applications/nuance/github/__tests__/issueevents/unlabeled.txt index dde464ab15..8323d661cd 100644 --- a/src/applications/nuance/github/__tests__/issueevents/unlabeled.txt +++ b/src/applications/nuance/github/__tests__/issueevents/unlabeled.txt @@ -79,5 +79,6 @@ "issue.number": 1, "id": 583218703, "uri": "https://github.com/epriestley/poems/issues/1#event-583218703", - "title.full": "GitHub epriestley/poems Issue #1 (Removed Label: bug)" + "title.full": "GitHub epriestley/poems Issue #1 (Removed Label: bug)", + "actor.id": 102631 } diff --git a/src/applications/nuance/github/__tests__/issueevents/unlocked.txt b/src/applications/nuance/github/__tests__/issueevents/unlocked.txt index 580a6170bb..31c87296cf 100644 --- a/src/applications/nuance/github/__tests__/issueevents/unlocked.txt +++ b/src/applications/nuance/github/__tests__/issueevents/unlocked.txt @@ -75,5 +75,6 @@ "issue.number": 1, "id": 583218062, "uri": "https://github.com/epriestley/poems/issues/1#event-583218062", - "title.full": "GitHub epriestley/poems Issue #1 (Unlocked)" + "title.full": "GitHub epriestley/poems Issue #1 (Unlocked)", + "actor.id": 102631 } diff --git a/src/applications/nuance/github/__tests__/repositoryevents/CreateEvent.tag.txt b/src/applications/nuance/github/__tests__/repositoryevents/CreateEvent.tag.txt index f0a8a3a1ad..1e73df40ff 100644 --- a/src/applications/nuance/github/__tests__/repositoryevents/CreateEvent.tag.txt +++ b/src/applications/nuance/github/__tests__/repositoryevents/CreateEvent.tag.txt @@ -33,5 +33,6 @@ "pull.number": null, "id": 3784548642, "uri": "https://github.com/epriestley/poems/commits/phabricator/diff/400", - "title.full": "GitHub epriestley/poems Tag phabricator/diff/400 (Created)" + "title.full": "GitHub epriestley/poems Tag phabricator/diff/400 (Created)", + "actor.id": 102631 } diff --git a/src/applications/nuance/github/__tests__/repositoryevents/IssueCommentEvent.created.pull.txt b/src/applications/nuance/github/__tests__/repositoryevents/IssueCommentEvent.created.pull.txt index 1991bb568e..9f25d5fdd0 100644 --- a/src/applications/nuance/github/__tests__/repositoryevents/IssueCommentEvent.created.pull.txt +++ b/src/applications/nuance/github/__tests__/repositoryevents/IssueCommentEvent.created.pull.txt @@ -161,5 +161,6 @@ "id": 3740938746, "uri": "https://github.com/epriestley/poems/pull/2#issuecomment-194282800", "title.full": "GitHub epriestley/poems Pull Request #2 (Comment)", - "comment": "wub wub" + "comment": "wub wub", + "actor.id": 102631 } diff --git a/src/applications/nuance/github/__tests__/repositoryevents/IssueCommentEvent.created.txt b/src/applications/nuance/github/__tests__/repositoryevents/IssueCommentEvent.created.txt index d22fd86e25..112b15bb9c 100644 --- a/src/applications/nuance/github/__tests__/repositoryevents/IssueCommentEvent.created.txt +++ b/src/applications/nuance/github/__tests__/repositoryevents/IssueCommentEvent.created.txt @@ -98,5 +98,6 @@ "id": 3733510485, "uri": "https://github.com/epriestley/poems/issues/1#issuecomment-193528669", "title.full": "GitHub epriestley/poems Issue #1 (Comment)", - "comment": "comment on issue" + "comment": "comment on issue", + "actor.id": 102631 } diff --git a/src/applications/nuance/github/__tests__/repositoryevents/IssuesEvent.closed.txt b/src/applications/nuance/github/__tests__/repositoryevents/IssuesEvent.closed.txt index 6e7d743303..b02827202b 100644 --- a/src/applications/nuance/github/__tests__/repositoryevents/IssuesEvent.closed.txt +++ b/src/applications/nuance/github/__tests__/repositoryevents/IssuesEvent.closed.txt @@ -69,5 +69,6 @@ "issue.number": 1, "id": 3740905151, "uri": "https://github.com/epriestley/poems/issues/1#event-3740905151", - "title.full": "GitHub epriestley/poems Issue #1 (Closed)" + "title.full": "GitHub epriestley/poems Issue #1 (Closed)", + "actor.id": 102631 } diff --git a/src/applications/nuance/github/__tests__/repositoryevents/IssuesEvent.opened.txt b/src/applications/nuance/github/__tests__/repositoryevents/IssuesEvent.opened.txt index 0b42f723d5..59ab8978bc 100644 --- a/src/applications/nuance/github/__tests__/repositoryevents/IssuesEvent.opened.txt +++ b/src/applications/nuance/github/__tests__/repositoryevents/IssuesEvent.opened.txt @@ -69,5 +69,6 @@ "issue.number": 1, "id": 3733509737, "uri": "https://github.com/epriestley/poems/issues/1#event-3733509737", - "title.full": "GitHub epriestley/poems Issue #1 (Created)" + "title.full": "GitHub epriestley/poems Issue #1 (Created)", + "actor.id": 102631 } diff --git a/src/applications/nuance/github/__tests__/repositoryevents/IssuesEvent.reopened.txt b/src/applications/nuance/github/__tests__/repositoryevents/IssuesEvent.reopened.txt index 3a0c5b7a20..aa27834884 100644 --- a/src/applications/nuance/github/__tests__/repositoryevents/IssuesEvent.reopened.txt +++ b/src/applications/nuance/github/__tests__/repositoryevents/IssuesEvent.reopened.txt @@ -69,5 +69,6 @@ "issue.number": 1, "id": 3740908680, "uri": "https://github.com/epriestley/poems/issues/1#event-3740908680", - "title.full": "GitHub epriestley/poems Issue #1 (Reopened)" + "title.full": "GitHub epriestley/poems Issue #1 (Reopened)", + "actor.id": 102631 } diff --git a/src/applications/nuance/github/__tests__/repositoryevents/PullRequestEvent.opened.txt b/src/applications/nuance/github/__tests__/repositoryevents/PullRequestEvent.opened.txt index f80649e724..1c863b2554 100644 --- a/src/applications/nuance/github/__tests__/repositoryevents/PullRequestEvent.opened.txt +++ b/src/applications/nuance/github/__tests__/repositoryevents/PullRequestEvent.opened.txt @@ -333,5 +333,6 @@ "pull.number": 2, "id": 3740936638, "uri": "https://github.com/epriestley/poems/pull/2#event-3740936638", - "title.full": "GitHub epriestley/poems Pull Request #2 (Created)" + "title.full": "GitHub epriestley/poems Pull Request #2 (Created)", + "actor.id": 102631 } diff --git a/src/applications/nuance/github/__tests__/repositoryevents/PushEvent.txt b/src/applications/nuance/github/__tests__/repositoryevents/PushEvent.txt index c6ecf1bdbc..67133676e7 100644 --- a/src/applications/nuance/github/__tests__/repositoryevents/PushEvent.txt +++ b/src/applications/nuance/github/__tests__/repositoryevents/PushEvent.txt @@ -44,5 +44,6 @@ "issue.number": null, "id": 3498724127, "uri": "https://github.com/epriestley/poems/commits/c829132d37c4c1da80d319942a5a1e500632b52f", - "title.full": "GitHub epriestley/poems Branch master (Pushed: c829132d37c4)" + "title.full": "GitHub epriestley/poems Branch master (Pushed: c829132d37c4)", + "actor.id": 102631 } diff --git a/src/applications/nuance/github/__tests__/repositoryevents/WatchEvent.started.txt b/src/applications/nuance/github/__tests__/repositoryevents/WatchEvent.started.txt index c23678f448..51c0550ccc 100644 --- a/src/applications/nuance/github/__tests__/repositoryevents/WatchEvent.started.txt +++ b/src/applications/nuance/github/__tests__/repositoryevents/WatchEvent.started.txt @@ -28,5 +28,6 @@ "pull.number": null, "id": 3740950917, "uri": null, - "title.full": "GitHub epriestley/poems User epriestley (Watched)" + "title.full": "GitHub epriestley/poems User epriestley (Watched)", + "actor.id": 102631 } From 7b0b820be1236fa4a13aa34e12d2bfe329c00c28 Mon Sep 17 00:00:00 2001 From: epriestley Date: Mon, 28 Mar 2016 12:01:18 -0700 Subject: [PATCH 18/42] Bridge GitHub users into Phabricator and attribute actions to them Summary: Ref T10538. Ref T10537. This creates PHIDs which represent GitHub users, and uses them as the actors for synchronized comments. I've just made them Doorkeeper objects. There are three major kinds of objects they //could// possibly be: - Nuance requestor objects. - External account objects. - Doorkeeper objects. I don't think we actually need distinct nuance requestor objects. These don't really do anything right now, and were originally created before Doorkeeper. I think Doorkeeper is a superset of nuance requestor functionality, and better developed and more flexible. Likewise, doorkeeper objects are much more flexible than external account objects, and it's nice to imagine that we can import from Twootfeed or whatever without needing to build full OAuth for it. I also like less stuff touching auth code, when possible. Making these separate from external accounts does make it a bit harder to reconcile external users with internal users, but I think that's OK, and that it's generally desirable to show the real source of a piece of content. That is, if I wrote a comment on GitHub but also have a Phabricator account, I think it's good to show "epriestley (GitHub)" (the GitHub user) as the author, not "epriestley" (the Phabricator user). I think this is generally less confusing overall, and we can add more linkage later to make it clearer. Test Plan: {F1194104} {F1194105} Reviewers: chad Reviewed By: chad Maniphest Tasks: T10537, T10538 Differential Revision: https://secure.phabricator.com/D15541 --- src/__phutil_library_map__.php | 4 + .../bridge/DoorkeeperBridgeGitHubUser.php | 120 ++++++++++++++++++ .../phid/DoorkeeperExternalObjectPHIDType.php | 47 +++++++ .../query/DoorkeeperExternalObjectQuery.php | 34 ++--- .../storage/DoorkeeperExternalObject.php | 23 +++- .../nuance/item/NuanceGitHubEventItemType.php | 102 +++++++++++++-- .../phid/PhabricatorPHIDConstants.php | 2 - .../edges/constants/PhabricatorEdgeConfig.php | 1 - 8 files changed, 294 insertions(+), 39 deletions(-) create mode 100644 src/applications/doorkeeper/bridge/DoorkeeperBridgeGitHubUser.php create mode 100644 src/applications/doorkeeper/phid/DoorkeeperExternalObjectPHIDType.php diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php index 9a2a1a7e19..df9a2dd3d6 100644 --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -843,12 +843,14 @@ phutil_register_library_map(array( 'DoorkeeperBridgeAsana' => 'applications/doorkeeper/bridge/DoorkeeperBridgeAsana.php', 'DoorkeeperBridgeGitHub' => 'applications/doorkeeper/bridge/DoorkeeperBridgeGitHub.php', 'DoorkeeperBridgeGitHubIssue' => 'applications/doorkeeper/bridge/DoorkeeperBridgeGitHubIssue.php', + 'DoorkeeperBridgeGitHubUser' => 'applications/doorkeeper/bridge/DoorkeeperBridgeGitHubUser.php', 'DoorkeeperBridgeJIRA' => 'applications/doorkeeper/bridge/DoorkeeperBridgeJIRA.php', 'DoorkeeperBridgeJIRATestCase' => 'applications/doorkeeper/bridge/__tests__/DoorkeeperBridgeJIRATestCase.php', 'DoorkeeperBridgedObjectCurtainExtension' => 'applications/doorkeeper/engineextension/DoorkeeperBridgedObjectCurtainExtension.php', 'DoorkeeperBridgedObjectInterface' => 'applications/doorkeeper/bridge/DoorkeeperBridgedObjectInterface.php', 'DoorkeeperDAO' => 'applications/doorkeeper/storage/DoorkeeperDAO.php', 'DoorkeeperExternalObject' => 'applications/doorkeeper/storage/DoorkeeperExternalObject.php', + 'DoorkeeperExternalObjectPHIDType' => 'applications/doorkeeper/phid/DoorkeeperExternalObjectPHIDType.php', 'DoorkeeperExternalObjectQuery' => 'applications/doorkeeper/query/DoorkeeperExternalObjectQuery.php', 'DoorkeeperFeedStoryPublisher' => 'applications/doorkeeper/engine/DoorkeeperFeedStoryPublisher.php', 'DoorkeeperFeedWorker' => 'applications/doorkeeper/worker/DoorkeeperFeedWorker.php', @@ -5017,6 +5019,7 @@ phutil_register_library_map(array( 'DoorkeeperBridgeAsana' => 'DoorkeeperBridge', 'DoorkeeperBridgeGitHub' => 'DoorkeeperBridge', 'DoorkeeperBridgeGitHubIssue' => 'DoorkeeperBridgeGitHub', + 'DoorkeeperBridgeGitHubUser' => 'DoorkeeperBridgeGitHub', 'DoorkeeperBridgeJIRA' => 'DoorkeeperBridge', 'DoorkeeperBridgeJIRATestCase' => 'PhabricatorTestCase', 'DoorkeeperBridgedObjectCurtainExtension' => 'PHUICurtainExtension', @@ -5025,6 +5028,7 @@ phutil_register_library_map(array( 'DoorkeeperDAO', 'PhabricatorPolicyInterface', ), + 'DoorkeeperExternalObjectPHIDType' => 'PhabricatorPHIDType', 'DoorkeeperExternalObjectQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', 'DoorkeeperFeedStoryPublisher' => 'Phobject', 'DoorkeeperFeedWorker' => 'FeedPushWorker', diff --git a/src/applications/doorkeeper/bridge/DoorkeeperBridgeGitHubUser.php b/src/applications/doorkeeper/bridge/DoorkeeperBridgeGitHubUser.php new file mode 100644 index 0000000000..3470894e5c --- /dev/null +++ b/src/applications/doorkeeper/bridge/DoorkeeperBridgeGitHubUser.php @@ -0,0 +1,120 @@ +getObjectType() !== self::OBJTYPE_GITHUB_USER) { + return false; + } + + return true; + } + + public function pullRefs(array $refs) { + $token = $this->getGitHubAccessToken(); + if (!strlen($token)) { + return null; + } + + $template = id(new PhutilGitHubFuture()) + ->setAccessToken($token); + + $futures = array(); + $id_map = mpull($refs, 'getObjectID', 'getObjectKey'); + foreach ($id_map as $key => $id) { + // GitHub doesn't provide a way to query for users by ID directly, but we + // can list all users, ordered by ID, starting at some particular ID, + // with a page size of one, which will achieve the desired effect. + $one_less = ($id - 1); + $uri = "/users?since={$one_less}&per_page=1"; + + $data = array(); + $futures[$key] = id(clone $template) + ->setRawGitHubQuery($uri, $data); + } + + $results = array(); + $failed = array(); + foreach (new FutureIterator($futures) as $key => $future) { + try { + $results[$key] = $future->resolve(); + } catch (Exception $ex) { + if (($ex instanceof HTTPFutureResponseStatus) && + ($ex->getStatusCode() == 404)) { + // TODO: Do we end up here for deleted objects and invisible + // objects? + } else { + phlog($ex); + $failed[$key] = $ex; + } + } + } + + $viewer = $this->getViewer(); + + foreach ($refs as $ref) { + $ref->setAttribute('name', pht('GitHub User %s', $ref->getObjectID())); + + $did_fail = idx($failed, $ref->getObjectKey()); + if ($did_fail) { + $ref->setSyncFailed(true); + continue; + } + + $result = idx($results, $ref->getObjectKey()); + if (!$result) { + continue; + } + + $body = $result->getBody(); + if (!is_array($body) || !count($body)) { + $ref->setSyncFailed(true); + continue; + } + + $spec = head($body); + if (!is_array($spec)) { + $ref->setSyncFailed(true); + continue; + } + + // Because we're using a paging query to load each user, if a user (say, + // user ID 123) does not exist for some reason, we might get the next + // user (say, user ID 124) back. Make sure the user we got back is really + // the user we expect. + $id = idx($spec, 'id'); + if ($id !== $ref->getObjectID()) { + $ref->setSyncFailed(true); + continue; + } + + $ref->setIsVisible(true); + $ref->setAttribute('api.raw', $spec); + $ref->setAttribute('name', $spec['login']); + + $obj = $ref->getExternalObject(); + $this->fillObjectFromData($obj, $spec); + + $unguarded = AphrontWriteGuard::beginScopedUnguardedWrites(); + $obj->save(); + unset($unguarded); + } + } + + public function fillObjectFromData(DoorkeeperExternalObject $obj, $spec) { + $uri = $spec['html_url']; + $obj->setObjectURI($uri); + + $login = $spec['login']; + + $obj->setDisplayName(pht('%s <%s>', $login, pht('GitHub'))); + } + +} diff --git a/src/applications/doorkeeper/phid/DoorkeeperExternalObjectPHIDType.php b/src/applications/doorkeeper/phid/DoorkeeperExternalObjectPHIDType.php new file mode 100644 index 0000000000..be9e32cf2a --- /dev/null +++ b/src/applications/doorkeeper/phid/DoorkeeperExternalObjectPHIDType.php @@ -0,0 +1,47 @@ +withPHIDs($phids); + } + + public function loadHandles( + PhabricatorHandleQuery $query, + array $handles, + array $objects) { + + foreach ($handles as $phid => $handle) { + $xobj = $objects[$phid]; + + $uri = $xobj->getObjectURI(); + $name = $xobj->getDisplayName(); + $full_name = $xobj->getDisplayFullName(); + + $handle + ->setURI($uri) + ->setName($name) + ->setFullName($full_name); + } + } + +} diff --git a/src/applications/doorkeeper/query/DoorkeeperExternalObjectQuery.php b/src/applications/doorkeeper/query/DoorkeeperExternalObjectQuery.php index 770678a687..bc794cc629 100644 --- a/src/applications/doorkeeper/query/DoorkeeperExternalObjectQuery.php +++ b/src/applications/doorkeeper/query/DoorkeeperExternalObjectQuery.php @@ -16,40 +16,32 @@ final class DoorkeeperExternalObjectQuery return $this; } - protected function loadPage() { - $table = new DoorkeeperExternalObject(); - $conn_r = $table->establishConnection('r'); - - $data = queryfx_all( - $conn_r, - 'SELECT * FROM %T %Q %Q %Q', - $table->getTableName(), - $this->buildWhereClause($conn_r), - $this->buildOrderClause($conn_r), - $this->buildLimitClause($conn_r)); - - return $table->loadAllFromArray($data); + public function newResultObject() { + return new DoorkeeperExternalObject(); } - protected function buildWhereClause(AphrontDatabaseConnection $conn_r) { - $where = array(); + protected function loadPage() { + return $this->loadStandardPage($this->newResultObject()); + } - if ($this->phids) { + protected function buildWhereClauseParts(AphrontDatabaseConnection $conn) { + $where = parent::buildWhereClauseParts($conn); + + if ($this->phids !== null) { $where[] = qsprintf( - $conn_r, + $conn, 'phid IN (%Ls)', $this->phids); } - if ($this->objectKeys) { + if ($this->objectKeys !== null) { $where[] = qsprintf( - $conn_r, + $conn, 'objectKey IN (%Ls)', $this->objectKeys); } - $where[] = $this->buildPagingClause($conn_r); - return $this->formatWhereClause($where); + return $where; } public function getQueryApplicationClass() { diff --git a/src/applications/doorkeeper/storage/DoorkeeperExternalObject.php b/src/applications/doorkeeper/storage/DoorkeeperExternalObject.php index 3050008594..9d8d3bc967 100644 --- a/src/applications/doorkeeper/storage/DoorkeeperExternalObject.php +++ b/src/applications/doorkeeper/storage/DoorkeeperExternalObject.php @@ -47,7 +47,7 @@ final class DoorkeeperExternalObject extends DoorkeeperDAO public function generatePHID() { return PhabricatorPHID::generateNewPHID( - PhabricatorPHIDConstants::PHID_TYPE_XOBJ); + DoorkeeperExternalObjectPHIDType::TYPECONST); } public function getProperty($key, $default = null) { @@ -83,6 +83,27 @@ final class DoorkeeperExternalObject extends DoorkeeperDAO return parent::save(); } + public function setDisplayName($display_name) { + return $this->setProperty('xobj.name.display', $display_name); + } + + public function getDisplayName() { + return $this->getProperty('xobj.name.display', pht('External Object')); + } + + public function setDisplayFullName($full_name) { + return $this->setProperty('xobj.name.display-full', $full_name); + } + + public function getDisplayFullName() { + $full_name = $this->getProperty('xobj.name.display-full'); + + if ($full_name !== null) { + return $full_name; + } + + return $this->getDisplayName(); + } /* -( PhabricatorPolicyInterface )----------------------------------------- */ diff --git a/src/applications/nuance/item/NuanceGitHubEventItemType.php b/src/applications/nuance/item/NuanceGitHubEventItemType.php index 21b371c506..3fef8b3da7 100644 --- a/src/applications/nuance/item/NuanceGitHubEventItemType.php +++ b/src/applications/nuance/item/NuanceGitHubEventItemType.php @@ -6,6 +6,7 @@ final class NuanceGitHubEventItemType const ITEMTYPE = 'github.event'; private $externalObject; + private $externalActor; public function getItemTypeDisplayName() { return pht('GitHub Event'); @@ -27,17 +28,18 @@ final class NuanceGitHubEventItemType $viewer = $this->getViewer(); $is_dirty = false; - // TODO: Link up the requestor, etc. - - $is_dirty = false; - $xobj = $this->reloadExternalObject($item); - if ($xobj) { $item->setItemProperty('doorkeeper.xobj.phid', $xobj->getPHID()); $is_dirty = true; } + $actor = $this->reloadExternalActor($item); + if ($actor) { + $item->setRequestorPHID($actor->getPHID()); + $is_dirty = true; + } + if ($item->getStatus() == NuanceItem::STATUS_IMPORTING) { $item->setStatus(NuanceItem::STATUS_ROUTING); $is_dirty = true; @@ -48,6 +50,21 @@ final class NuanceGitHubEventItemType } } + private function getDoorkeeperActorRef(NuanceItem $item) { + $raw = $this->newRawEvent($item); + + $user_id = $raw->getActorGitHubUserID(); + if (!$user_id) { + return null; + } + + $ref_type = DoorkeeperBridgeGitHubUser::OBJTYPE_GITHUB_USER; + + return $this->newDoorkeeperRef() + ->setObjectType($ref_type) + ->setObjectID($user_id); + } + private function getDoorkeeperRef(NuanceItem $item) { $raw = $this->newRawEvent($item); @@ -64,19 +81,52 @@ final class NuanceGitHubEventItemType return null; } - return id(new DoorkeeperObjectRef()) - ->setApplicationType(DoorkeeperBridgeGitHub::APPTYPE_GITHUB) - ->setApplicationDomain(DoorkeeperBridgeGitHub::APPDOMAIN_GITHUB) + return $this->newDoorkeeperRef() ->setObjectType($ref_type) ->setObjectID($full_ref); } + private function newDoorkeeperRef() { + return id(new DoorkeeperObjectRef()) + ->setApplicationType(DoorkeeperBridgeGitHub::APPTYPE_GITHUB) + ->setApplicationDomain(DoorkeeperBridgeGitHub::APPDOMAIN_GITHUB); + } + private function reloadExternalObject(NuanceItem $item, $local = false) { $ref = $this->getDoorkeeperRef($item); if (!$ref) { return null; } + $xobj = $this->reloadExternalRef($item, $ref, $local); + + if ($xobj) { + $this->externalObject = $xobj; + } + + return $xobj; + } + + private function reloadExternalActor(NuanceItem $item, $local = false) { + $ref = $this->getDoorkeeperActorRef($item); + if (!$ref) { + return null; + } + + $xobj = $this->reloadExternalRef($item, $ref, $local); + + if ($xobj) { + $this->externalActor = $xobj; + } + + return $xobj; + } + + private function reloadExternalRef( + NuanceItem $item, + DoorkeeperObjectRef $ref, + $local) { + $source = $item->getSource(); $token = $source->getSourceProperty('github.token'); $token = new PhutilOpaqueEnvelope($token); @@ -97,10 +147,6 @@ final class NuanceGitHubEventItemType $xobj = $ref->getExternalObject(); } - if ($xobj) { - $this->externalObject = $xobj; - } - return $xobj; } @@ -121,6 +167,23 @@ final class NuanceGitHubEventItemType return null; } + private function getExternalActor(NuanceItem $item) { + if ($this->externalActor === null) { + $xobj = $this->reloadExternalActor($item, $local = true); + if ($xobj) { + $this->externalActor = $xobj; + } else { + $this->externalActor = false; + } + } + + if ($this->externalActor) { + return $this->externalActor; + } + + return null; + } + private function newRawEvent(NuanceItem $item) { $type = $item->getItemProperty('api.type'); $raw = $item->getItemProperty('api.raw', array()); @@ -174,6 +237,13 @@ final class NuanceGitHubEventItemType } } + $xactor = $this->getExternalActor($item); + if ($xactor) { + $panels[] = $this->newCurtainPanel($item) + ->setHeaderText(pht('GitHub Actor')) + ->appendChild($viewer->renderHandle($xactor->getPHID())); + } + return $panels; } @@ -363,8 +433,12 @@ final class NuanceGitHubEventItemType } protected function getActingAsPHID(NuanceItem $item) { - // TODO: This should be an external account PHID representing the original - // GitHub user. + $actor_phid = $item->getRequestorPHID(); + + if ($actor_phid) { + return $actor_phid; + } + return parent::getActingAsPHID($item); } diff --git a/src/applications/phid/PhabricatorPHIDConstants.php b/src/applications/phid/PhabricatorPHIDConstants.php index 6e6dfca6dc..91330bf499 100644 --- a/src/applications/phid/PhabricatorPHIDConstants.php +++ b/src/applications/phid/PhabricatorPHIDConstants.php @@ -10,8 +10,6 @@ final class PhabricatorPHIDConstants extends Phobject { const PHID_TYPE_XCMT = 'XCMT'; - const PHID_TYPE_XOBJ = 'XOBJ'; - const PHID_TYPE_VOID = 'VOID'; const PHID_VOID = 'PHID-VOID-00000000000000000000'; diff --git a/src/infrastructure/edges/constants/PhabricatorEdgeConfig.php b/src/infrastructure/edges/constants/PhabricatorEdgeConfig.php index 4e256dd5ca..0473f2426d 100644 --- a/src/infrastructure/edges/constants/PhabricatorEdgeConfig.php +++ b/src/infrastructure/edges/constants/PhabricatorEdgeConfig.php @@ -17,7 +17,6 @@ final class PhabricatorEdgeConfig extends PhabricatorEdgeConstants { static $class_map = array( PhabricatorPHIDConstants::PHID_TYPE_TOBJ => 'HarbormasterObject', - PhabricatorPHIDConstants::PHID_TYPE_XOBJ => 'DoorkeeperExternalObject', ); $class = idx($class_map, $phid_type); From 6dc30ecc8ef1006b4b2614ae7e0506414c49722b Mon Sep 17 00:00:00 2001 From: Aviv Eyal Date: Mon, 28 Mar 2016 23:02:41 +0000 Subject: [PATCH 19/42] Drive Herald edits via transactions Summary: This is kinda bad in terms of UI (It just makes a json of the thing and diffs that), but it's a start. Test Plan: edit rule, create rule, add/remove/edit conditions, actions Reviewers: #blessed_reviewers, epriestley Reviewed By: #blessed_reviewers, epriestley Subscribers: Korvin Differential Revision: https://secure.phabricator.com/D15542 --- src/__phutil_library_map__.php | 2 + .../controller/HeraldRuleController.php | 49 +++++++++---- .../herald/editor/HeraldRuleEditor.php | 28 ++++++- .../herald/editor/HeraldRuleSerializer.php | 73 +++++++++++++++++++ .../herald/storage/HeraldRuleTransaction.php | 43 +++++++++++ 5 files changed, 179 insertions(+), 16 deletions(-) create mode 100644 src/applications/herald/editor/HeraldRuleSerializer.php diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php index df9a2dd3d6..c21a044fbc 100644 --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -1230,6 +1230,7 @@ phutil_register_library_map(array( 'HeraldRulePHIDType' => 'applications/herald/phid/HeraldRulePHIDType.php', 'HeraldRuleQuery' => 'applications/herald/query/HeraldRuleQuery.php', 'HeraldRuleSearchEngine' => 'applications/herald/query/HeraldRuleSearchEngine.php', + 'HeraldRuleSerializer' => 'applications/herald/editor/HeraldRuleSerializer.php', 'HeraldRuleTestCase' => 'applications/herald/storage/__tests__/HeraldRuleTestCase.php', 'HeraldRuleTransaction' => 'applications/herald/storage/HeraldRuleTransaction.php', 'HeraldRuleTransactionComment' => 'applications/herald/storage/HeraldRuleTransactionComment.php', @@ -5497,6 +5498,7 @@ phutil_register_library_map(array( 'HeraldRulePHIDType' => 'PhabricatorPHIDType', 'HeraldRuleQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', 'HeraldRuleSearchEngine' => 'PhabricatorApplicationSearchEngine', + 'HeraldRuleSerializer' => 'Phobject', 'HeraldRuleTestCase' => 'PhabricatorTestCase', 'HeraldRuleTransaction' => 'PhabricatorApplicationTransaction', 'HeraldRuleTransactionComment' => 'PhabricatorApplicationTransactionComment', diff --git a/src/applications/herald/controller/HeraldRuleController.php b/src/applications/herald/controller/HeraldRuleController.php index d7963a5193..0289dce2e6 100644 --- a/src/applications/herald/controller/HeraldRuleController.php +++ b/src/applications/herald/controller/HeraldRuleController.php @@ -259,18 +259,15 @@ final class HeraldRuleController extends HeraldController { } private function saveRule(HeraldAdapter $adapter, $rule, $request) { - $rule->setName($request->getStr('name')); + $new_name = $request->getStr('name'); $match_all = ($request->getStr('must_match') == 'all'); - $rule->setMustMatchAll((int)$match_all); $repetition_policy_param = $request->getStr('repetition_policy'); - $rule->setRepetitionPolicy( - HeraldRepetitionPolicyConfig::toInt($repetition_policy_param)); $e_name = true; $errors = array(); - if (!strlen($rule->getName())) { + if (!strlen($new_name)) { $e_name = pht('Required'); $errors[] = pht('Rule must have a name.'); } @@ -343,19 +340,41 @@ final class HeraldRuleController extends HeraldController { $actions[] = $obj; } + if (!$errors) { + $new_state = id(new HeraldRuleSerializer())->serializeRuleComponents( + $match_all, + $conditions, + $actions, + $repetition_policy_param); + + $xactions = array(); + $xactions[] = id(new HeraldRuleTransaction()) + ->setTransactionType(HeraldRuleTransaction::TYPE_EDIT) + ->setNewValue($new_state); + $xactions[] = id(new HeraldRuleTransaction()) + ->setTransactionType(HeraldRuleTransaction::TYPE_NAME) + ->setNewValue($new_name); + + try { + id(new HeraldRuleEditor()) + ->setActor($this->getViewer()) + ->setContinueOnNoEffect(true) + ->setContentSourceFromRequest($request) + ->applyTransactions($rule, $xactions); + return array(null, null); + } catch (Exception $ex) { + $errors[] = $ex->getMessage(); + } + } + + // mutate current rule, so it would be sent to the client in the right state + $rule->setMustMatchAll((int)$match_all); + $rule->setName($new_name); + $rule->setRepetitionPolicy( + HeraldRepetitionPolicyConfig::toInt($repetition_policy_param)); $rule->attachConditions($conditions); $rule->attachActions($actions); - if (!$errors) { - $edit_action = $rule->getID() ? 'edit' : 'create'; - - $rule->openTransaction(); - $rule->save(); - $rule->saveConditions($conditions); - $rule->saveActions($actions); - $rule->saveTransaction(); - } - return array($e_name, $errors); } diff --git a/src/applications/herald/editor/HeraldRuleEditor.php b/src/applications/herald/editor/HeraldRuleEditor.php index 635c24654c..de9bb01ef2 100644 --- a/src/applications/herald/editor/HeraldRuleEditor.php +++ b/src/applications/herald/editor/HeraldRuleEditor.php @@ -15,6 +15,8 @@ final class HeraldRuleEditor $types = parent::getTransactionTypes(); $types[] = PhabricatorTransactions::TYPE_COMMENT; + $types[] = HeraldRuleTransaction::TYPE_EDIT; + $types[] = HeraldRuleTransaction::TYPE_NAME; $types[] = HeraldRuleTransaction::TYPE_DISABLE; return $types; @@ -27,6 +29,11 @@ final class HeraldRuleEditor switch ($xaction->getTransactionType()) { case HeraldRuleTransaction::TYPE_DISABLE: return (int)$object->getIsDisabled(); + case HeraldRuleTransaction::TYPE_EDIT: + return id(new HeraldRuleSerializer()) + ->serializeRule($object); + case HeraldRuleTransaction::TYPE_NAME: + return $object->getName(); } } @@ -38,8 +45,10 @@ final class HeraldRuleEditor switch ($xaction->getTransactionType()) { case HeraldRuleTransaction::TYPE_DISABLE: return (int)$xaction->getNewValue(); + case HeraldRuleTransaction::TYPE_EDIT: + case HeraldRuleTransaction::TYPE_NAME: + return $xaction->getNewValue(); } - } protected function applyCustomInternalTransaction( @@ -49,6 +58,17 @@ final class HeraldRuleEditor switch ($xaction->getTransactionType()) { case HeraldRuleTransaction::TYPE_DISABLE: return $object->setIsDisabled($xaction->getNewValue()); + case HeraldRuleTransaction::TYPE_NAME: + return $object->setName($xaction->getNewValue()); + case HeraldRuleTransaction::TYPE_EDIT: + $new_state = id(new HeraldRuleSerializer()) + ->deserializeRuleComponents($xaction->getNewValue()); + $object->setMustMatchAll((int)$new_state['match_all']); + $object->attachConditions($new_state['conditions']); + $object->attachActions($new_state['actions']); + $object->setRepetitionPolicy( + HeraldRepetitionPolicyConfig::toInt($new_state['repetition_policy'])); + return $object; } } @@ -56,6 +76,12 @@ final class HeraldRuleEditor protected function applyCustomExternalTransaction( PhabricatorLiskDAO $object, PhabricatorApplicationTransaction $xaction) { + switch ($xaction->getTransactionType()) { + case HeraldRuleTransaction::TYPE_EDIT: + $object->saveConditions($object->getConditions()); + $object->saveActions($object->getActions()); + break; + } return; } diff --git a/src/applications/herald/editor/HeraldRuleSerializer.php b/src/applications/herald/editor/HeraldRuleSerializer.php new file mode 100644 index 0000000000..d1b2527aaa --- /dev/null +++ b/src/applications/herald/editor/HeraldRuleSerializer.php @@ -0,0 +1,73 @@ +serializeRuleComponents( + (bool)$rule->getMustMatchAll(), + $rule->getConditions(), + $rule->getActions(), + HeraldRepetitionPolicyConfig::toString($rule->getRepetitionPolicy())); + } + + public function serializeRuleComponents( + $match_all, + array $conditions, + array $actions, + $repetition_policy) { + + assert_instances_of($conditions, 'HeraldCondition'); + assert_instances_of($actions, 'HeraldActionRecord'); + + $conditions_array = array(); + foreach ($conditions as $condition) { + $conditions_array[] = array( + 'field' => $condition->getFieldName(), + 'condition' => $condition->getFieldCondition(), + 'value' => $condition->getValue(), + ); + } + + $actions_array = array(); + foreach ($actions as $action) { + $actions_array[] = array( + 'action' => $action->getAction(), + 'target' => $action->getTarget(), + ); + } + + return array( + 'match_all' => $match_all, + 'conditions' => $conditions_array, + 'actions' => $actions_array, + 'repetition_policy' => $repetition_policy, + ); + } + + public function deserializeRuleComponents(array $serialized) { + $deser_conditions = array(); + foreach ($serialized['conditions'] as $condition) { + $deser_conditions[] = id(new HeraldCondition()) + ->setFieldName($condition['field']) + ->setFieldCondition($condition['condition']) + ->setValue($condition['value']); + } + + $deser_actions = array(); + foreach ($serialized['actions'] as $action) { + $deser_actions[] = id(new HeraldActionRecord()) + ->setAction($action['action']) + ->setTarget($action['target']); + } + + return array( + 'match_all' => $serialized['match_all'], + 'conditions' => $deser_conditions, + 'actions' => $deser_actions, + 'repetition_policy' => $serialized['repetition_policy'], + ); + } + +} diff --git a/src/applications/herald/storage/HeraldRuleTransaction.php b/src/applications/herald/storage/HeraldRuleTransaction.php index 8d4201faf6..b1bd563749 100644 --- a/src/applications/herald/storage/HeraldRuleTransaction.php +++ b/src/applications/herald/storage/HeraldRuleTransaction.php @@ -4,6 +4,7 @@ final class HeraldRuleTransaction extends PhabricatorApplicationTransaction { const TYPE_EDIT = 'herald:edit'; + const TYPE_NAME = 'herald:name'; const TYPE_DISABLE = 'herald:disable'; public function getApplicationName() { @@ -45,6 +46,8 @@ final class HeraldRuleTransaction } else { return pht('Enabled'); } + case self::TYPE_NAME: + return pht('Renamed'); } return parent::getActionName(); @@ -84,9 +87,49 @@ final class HeraldRuleTransaction '%s enabled this rule.', $this->renderHandleLink($author_phid)); } + case self::TYPE_NAME: + if ($old == null) { + return pht( + '%s created this rule.', + $this->renderHandleLink($author_phid)); + } else { + return pht( + '%s renamed this rule from "%s" to "%s".', + $this->renderHandleLink($author_phid), + $old, + $new); + } + case self::TYPE_EDIT: + return pht( + '%s edited this rule.', + $this->renderHandleLink($author_phid)); } return parent::getTitle(); } + public function hasChangeDetails() { + switch ($this->getTransactionType()) { + case self::TYPE_EDIT: + return true; + } + return parent::hasChangeDetails(); + } + + public function renderChangeDetails(PhabricatorUser $viewer) { + $json = new PhutilJSON(); + switch ($this->getTransactionType()) { + case self::TYPE_EDIT: + return $this->renderTextCorpusChangeDetails( + $viewer, + $json->encodeFormatted($this->getOldValue()), + $json->encodeFormatted($this->getNewValue())); + } + + return $this->renderTextCorpusChangeDetails( + $viewer, + $this->getOldValue(), + $this->getNewValue()); + } + } From f50693de61d9cd9f98ad94dc8315933242284320 Mon Sep 17 00:00:00 2001 From: epriestley Date: Tue, 29 Mar 2016 07:12:05 -0700 Subject: [PATCH 20/42] Remove dedicated storage for NuanceRequestor Summary: Ref T10537. Currently, Nuance has a `NuanceRequestor` object, intended to represent the external user who created content (e.g., a GitHub account or a Twitter account or whatever). This object is currently almost unused, and its design predates Doorkeeper. In D15541, I chose to use doorkeeper objects instead of NuanceRequestor objects to represent requestors. I don't currently anticipate a need for such an object, given that we have Doorkeeper. If we do need it in the future for some reason, it would be fairly easy to restore it, create a requestor type which wraps a Doorkeeper object, and then migrate. Not super thrilling to do that, but not a huge mess. `NuanceItem` still has a `requestorPHID`, but this is now a less formal object PHID instead of a more formal Requestor-object PHID, and holds a doorkeeper exeternal object PHID for GitHub events. Test Plan: - Grepped for `nuancerequestor`. - Ran `bin/storage upgrade -f`. - Grepped for `requestor`, remaining uses of this term seem reasonable/correct. Reviewers: chad Reviewed By: chad Maniphest Tasks: T10537 Differential Revision: https://secure.phabricator.com/D15546 --- .../20160329.nuance.01.requestor.sql | 1 + .../20160329.nuance.02.requestorsource.sql | 1 + .../20160329.nuance.03.requestorxaction.sql | 1 + .../20160329.nuance.04.requestorcomment.sql | 1 + src/__phutil_library_map__.php | 24 --- .../PhabricatorNuanceApplication.php | 5 - .../NuanceRequestorEditController.php | 33 ----- .../NuanceRequestorViewController.php | 27 ---- .../nuance/editor/NuanceRequestorEditor.php | 75 ---------- .../nuance/phid/NuanceRequestorPHIDType.php | 43 ------ .../nuance/query/NuanceRequestorQuery.php | 47 ------ .../query/NuanceRequestorTransactionQuery.php | 10 -- .../NuancePhabricatorFormSourceDefinition.php | 5 - .../nuance/source/NuanceSourceDefinition.php | 6 - .../nuance/storage/NuanceItem.php | 8 - .../nuance/storage/NuanceRequestor.php | 137 ------------------ .../nuance/storage/NuanceRequestorSource.php | 34 ----- .../storage/NuanceRequestorTransaction.php | 17 --- .../NuanceRequestorTransactionComment.php | 10 -- 19 files changed, 4 insertions(+), 481 deletions(-) create mode 100644 resources/sql/autopatches/20160329.nuance.01.requestor.sql create mode 100644 resources/sql/autopatches/20160329.nuance.02.requestorsource.sql create mode 100644 resources/sql/autopatches/20160329.nuance.03.requestorxaction.sql create mode 100644 resources/sql/autopatches/20160329.nuance.04.requestorcomment.sql delete mode 100644 src/applications/nuance/controller/NuanceRequestorEditController.php delete mode 100644 src/applications/nuance/controller/NuanceRequestorViewController.php delete mode 100644 src/applications/nuance/editor/NuanceRequestorEditor.php delete mode 100644 src/applications/nuance/phid/NuanceRequestorPHIDType.php delete mode 100644 src/applications/nuance/query/NuanceRequestorQuery.php delete mode 100644 src/applications/nuance/query/NuanceRequestorTransactionQuery.php delete mode 100644 src/applications/nuance/storage/NuanceRequestor.php delete mode 100644 src/applications/nuance/storage/NuanceRequestorSource.php delete mode 100644 src/applications/nuance/storage/NuanceRequestorTransaction.php delete mode 100644 src/applications/nuance/storage/NuanceRequestorTransactionComment.php diff --git a/resources/sql/autopatches/20160329.nuance.01.requestor.sql b/resources/sql/autopatches/20160329.nuance.01.requestor.sql new file mode 100644 index 0000000000..63b0a30210 --- /dev/null +++ b/resources/sql/autopatches/20160329.nuance.01.requestor.sql @@ -0,0 +1 @@ +DROP TABLE IF EXISTS {$NAMESPACE}_nuance.nuance_requestor; diff --git a/resources/sql/autopatches/20160329.nuance.02.requestorsource.sql b/resources/sql/autopatches/20160329.nuance.02.requestorsource.sql new file mode 100644 index 0000000000..1977022622 --- /dev/null +++ b/resources/sql/autopatches/20160329.nuance.02.requestorsource.sql @@ -0,0 +1 @@ +DROP TABLE IF EXISTS {$NAMESPACE}_nuance.nuance_requestorsource; diff --git a/resources/sql/autopatches/20160329.nuance.03.requestorxaction.sql b/resources/sql/autopatches/20160329.nuance.03.requestorxaction.sql new file mode 100644 index 0000000000..f05c589a5e --- /dev/null +++ b/resources/sql/autopatches/20160329.nuance.03.requestorxaction.sql @@ -0,0 +1 @@ +DROP TABLE IF EXISTS {$NAMESPACE}_nuance.nuance_requestortransaction; diff --git a/resources/sql/autopatches/20160329.nuance.04.requestorcomment.sql b/resources/sql/autopatches/20160329.nuance.04.requestorcomment.sql new file mode 100644 index 0000000000..f97db8514b --- /dev/null +++ b/resources/sql/autopatches/20160329.nuance.04.requestorcomment.sql @@ -0,0 +1 @@ +DROP TABLE IF EXISTS {$NAMESPACE}_nuance.nuance_requestortransaction_comment; diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php index c21a044fbc..134e2bbcbe 100644 --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -1479,16 +1479,6 @@ phutil_register_library_map(array( 'NuanceQueueTransactionComment' => 'applications/nuance/storage/NuanceQueueTransactionComment.php', 'NuanceQueueTransactionQuery' => 'applications/nuance/query/NuanceQueueTransactionQuery.php', 'NuanceQueueViewController' => 'applications/nuance/controller/NuanceQueueViewController.php', - 'NuanceRequestor' => 'applications/nuance/storage/NuanceRequestor.php', - 'NuanceRequestorEditController' => 'applications/nuance/controller/NuanceRequestorEditController.php', - 'NuanceRequestorEditor' => 'applications/nuance/editor/NuanceRequestorEditor.php', - 'NuanceRequestorPHIDType' => 'applications/nuance/phid/NuanceRequestorPHIDType.php', - 'NuanceRequestorQuery' => 'applications/nuance/query/NuanceRequestorQuery.php', - 'NuanceRequestorSource' => 'applications/nuance/storage/NuanceRequestorSource.php', - 'NuanceRequestorTransaction' => 'applications/nuance/storage/NuanceRequestorTransaction.php', - 'NuanceRequestorTransactionComment' => 'applications/nuance/storage/NuanceRequestorTransactionComment.php', - 'NuanceRequestorTransactionQuery' => 'applications/nuance/query/NuanceRequestorTransactionQuery.php', - 'NuanceRequestorViewController' => 'applications/nuance/controller/NuanceRequestorViewController.php', 'NuanceSchemaSpec' => 'applications/nuance/storage/NuanceSchemaSpec.php', 'NuanceSource' => 'applications/nuance/storage/NuanceSource.php', 'NuanceSourceActionController' => 'applications/nuance/controller/NuanceSourceActionController.php', @@ -5797,20 +5787,6 @@ phutil_register_library_map(array( 'NuanceQueueTransactionComment' => 'PhabricatorApplicationTransactionComment', 'NuanceQueueTransactionQuery' => 'PhabricatorApplicationTransactionQuery', 'NuanceQueueViewController' => 'NuanceQueueController', - 'NuanceRequestor' => array( - 'NuanceDAO', - 'PhabricatorPolicyInterface', - 'PhabricatorApplicationTransactionInterface', - ), - 'NuanceRequestorEditController' => 'NuanceController', - 'NuanceRequestorEditor' => 'PhabricatorApplicationTransactionEditor', - 'NuanceRequestorPHIDType' => 'PhabricatorPHIDType', - 'NuanceRequestorQuery' => 'NuanceQuery', - 'NuanceRequestorSource' => 'NuanceDAO', - 'NuanceRequestorTransaction' => 'NuanceTransaction', - 'NuanceRequestorTransactionComment' => 'PhabricatorApplicationTransactionComment', - 'NuanceRequestorTransactionQuery' => 'PhabricatorApplicationTransactionQuery', - 'NuanceRequestorViewController' => 'NuanceController', 'NuanceSchemaSpec' => 'PhabricatorConfigSchemaSpec', 'NuanceSource' => array( 'NuanceDAO', diff --git a/src/applications/nuance/application/PhabricatorNuanceApplication.php b/src/applications/nuance/application/PhabricatorNuanceApplication.php index 27f683380f..dede1175ab 100644 --- a/src/applications/nuance/application/PhabricatorNuanceApplication.php +++ b/src/applications/nuance/application/PhabricatorNuanceApplication.php @@ -56,11 +56,6 @@ final class PhabricatorNuanceApplication extends PhabricatorApplication { $this->getEditRoutePattern('edit/') => 'NuanceQueueEditController', 'view/(?P[1-9]\d*)/' => 'NuanceQueueViewController', ), - 'requestor/' => array( - 'view/(?P[1-9]\d*)/' => 'NuanceRequestorViewController', - 'edit/(?P[1-9]\d*)/' => 'NuanceRequestorEditController', - 'new/' => 'NuanceRequestorEditController', - ), ), '/action/' => array( '(?P[1-9]\d*)/(?P.*)' => 'NuanceSourceActionController', diff --git a/src/applications/nuance/controller/NuanceRequestorEditController.php b/src/applications/nuance/controller/NuanceRequestorEditController.php deleted file mode 100644 index 2efc49f711..0000000000 --- a/src/applications/nuance/controller/NuanceRequestorEditController.php +++ /dev/null @@ -1,33 +0,0 @@ -getViewer(); - $id = $request->getURIData('id'); - - if (!$id) { - $requestor = new NuanceRequestor(); - - } else { - $requestor = id(new NuanceRequestorQuery()) - ->setViewer($viewer) - ->withIDs(array($id)) - ->executeOne(); - } - - if (!$requestor) { - return new Aphront404Response(); - } - - $crumbs = $this->buildApplicationCrumbs(); - $title = pht('TODO'); - - return $this->buildApplicationPage( - $crumbs, - array( - 'title' => $title, - )); - } - -} diff --git a/src/applications/nuance/controller/NuanceRequestorViewController.php b/src/applications/nuance/controller/NuanceRequestorViewController.php deleted file mode 100644 index 8f6912c4d7..0000000000 --- a/src/applications/nuance/controller/NuanceRequestorViewController.php +++ /dev/null @@ -1,27 +0,0 @@ -getViewer(); - $id = $request->getURIData('id'); - - $requestor = id(new NuanceRequestorQuery()) - ->setViewer($viewer) - ->withIDs(array($id)) - ->executeOne(); - - if (!$requestor) { - return new Aphront404Response(); - } - - $crumbs = $this->buildApplicationCrumbs(); - $title = 'TODO'; - - return $this->buildApplicationPage( - $crumbs, - array( - 'title' => $title, - )); - } -} diff --git a/src/applications/nuance/editor/NuanceRequestorEditor.php b/src/applications/nuance/editor/NuanceRequestorEditor.php deleted file mode 100644 index 4ca4c875ff..0000000000 --- a/src/applications/nuance/editor/NuanceRequestorEditor.php +++ /dev/null @@ -1,75 +0,0 @@ -getTransactionType()) { - case NuanceRequestorTransaction::TYPE_PROPERTY: - $key = $xaction->getMetadataValue( - NuanceRequestorTransaction::PROPERTY_KEY); - return $object->getNuanceProperty($key); - } - - return parent::getCustomTransactionOldValue($object, $xaction); - } - - protected function getCustomTransactionNewValue( - PhabricatorLiskDAO $object, - PhabricatorApplicationTransaction $xaction) { - - switch ($xaction->getTransactionType()) { - case NuanceRequestorTransaction::TYPE_PROPERTY: - return $xaction->getNewValue(); - } - - return parent::getCustomTransactionNewValue($object, $xaction); - } - - protected function applyCustomInternalTransaction( - PhabricatorLiskDAO $object, - PhabricatorApplicationTransaction $xaction) { - - switch ($xaction->getTransactionType()) { - case NuanceRequestorTransaction::TYPE_PROPERTY: - $key = $xaction->getMetadataValue( - NuanceRequestorTransaction::PROPERTY_KEY); - $object->setNuanceProperty($key, $xaction->getNewValue()); - break; - } - } - - protected function applyCustomExternalTransaction( - PhabricatorLiskDAO $object, - PhabricatorApplicationTransaction $xaction) { - - switch ($xaction->getTransactionType()) { - case NuanceRequestorTransaction::TYPE_PROPERTY: - return; - } - - return parent::applyCustomExternalTransaction($object, $xaction); - } -} diff --git a/src/applications/nuance/phid/NuanceRequestorPHIDType.php b/src/applications/nuance/phid/NuanceRequestorPHIDType.php deleted file mode 100644 index a2442d3b48..0000000000 --- a/src/applications/nuance/phid/NuanceRequestorPHIDType.php +++ /dev/null @@ -1,43 +0,0 @@ -withPHIDs($phids); - } - - public function loadHandles( - PhabricatorHandleQuery $query, - array $handles, - array $objects) { - - $viewer = $query->getViewer(); - foreach ($handles as $phid => $handle) { - $requestor = $objects[$phid]; - - // TODO: This is currently useless and should be far more informative. - $handle->setName(pht('Requestor %d', $requestor->getID())); - - $handle->setURI($requestor->getURI()); - } - } - -} diff --git a/src/applications/nuance/query/NuanceRequestorQuery.php b/src/applications/nuance/query/NuanceRequestorQuery.php deleted file mode 100644 index 49e4e61e94..0000000000 --- a/src/applications/nuance/query/NuanceRequestorQuery.php +++ /dev/null @@ -1,47 +0,0 @@ -ids = $ids; - return $this; - } - - public function withPHIDs(array $phids) { - $this->phids = $phids; - return $this; - } - - public function newObject() { - return new NuanceRequestor(); - } - - protected function loadPage() { - return $this->loadStandardPage($this->newObject()); - } - - protected function buildWhereClauseParts(AphrontDatabaseConnection $conn) { - $where = parent::buildWhereClauseParts($conn); - - if ($this->ids !== null) { - $where[] = qsprintf( - $conn, - 'id IN (%Ld)', - $this->ids); - } - - if ($this->phids !== null) { - $where[] = qsprintf( - $conn, - 'phid IN (%Ls)', - $this->phids); - } - - return $where; - } - -} diff --git a/src/applications/nuance/query/NuanceRequestorTransactionQuery.php b/src/applications/nuance/query/NuanceRequestorTransactionQuery.php deleted file mode 100644 index 5ecb41c47d..0000000000 --- a/src/applications/nuance/query/NuanceRequestorTransactionQuery.php +++ /dev/null @@ -1,10 +0,0 @@ -newItemFromProperties( - $requestor, $properties, $content_source); diff --git a/src/applications/nuance/source/NuanceSourceDefinition.php b/src/applications/nuance/source/NuanceSourceDefinition.php index 742837ef82..99d79f8f31 100644 --- a/src/applications/nuance/source/NuanceSourceDefinition.php +++ b/src/applications/nuance/source/NuanceSourceDefinition.php @@ -149,7 +149,6 @@ abstract class NuanceSourceDefinition extends Phobject { } protected function newItemFromProperties( - NuanceRequestor $requestor, array $properties, PhabricatorContentSource $content_source) { @@ -166,10 +165,6 @@ abstract class NuanceSourceDefinition extends Phobject { ->setTransactionType(NuanceItemTransaction::TYPE_SOURCE) ->setNewValue($source->getPHID()); - $xactions[] = id(new NuanceItemTransaction()) - ->setTransactionType(NuanceItemTransaction::TYPE_REQUESTOR) - ->setNewValue($requestor->getPHID()); - // TODO: Eventually, apply real routing rules. For now, just put everything // in the default queue for the source. $xactions[] = id(new NuanceItemTransaction()) @@ -185,7 +180,6 @@ abstract class NuanceSourceDefinition extends Phobject { $editor = id(new NuanceItemEditor()) ->setActor($actor) - ->setActingAsPHID($requestor->getActingAsPHID()) ->setContentSource($content_source); $editor->applyTransactions($item, $xactions); diff --git a/src/applications/nuance/storage/NuanceItem.php b/src/applications/nuance/storage/NuanceItem.php index a21a5443c2..2eadcdb2d9 100644 --- a/src/applications/nuance/storage/NuanceItem.php +++ b/src/applications/nuance/storage/NuanceItem.php @@ -87,14 +87,6 @@ final class NuanceItem return '/nuance/item/view/'.$this->getID().'/'; } - public function getRequestor() { - return $this->assertAttached($this->requestor); - } - - public function attachRequestor(NuanceRequestor $requestor) { - return $this->requestor = $requestor; - } - public function getSource() { return $this->assertAttached($this->source); } diff --git a/src/applications/nuance/storage/NuanceRequestor.php b/src/applications/nuance/storage/NuanceRequestor.php deleted file mode 100644 index d4341d0b24..0000000000 --- a/src/applications/nuance/storage/NuanceRequestor.php +++ /dev/null @@ -1,137 +0,0 @@ - true, - self::CONFIG_SERIALIZATION => array( - 'data' => self::SERIALIZATION_JSON, - ), - ) + parent::getConfiguration(); - } - - public function generatePHID() { - return PhabricatorPHID::generateNewPHID( - NuanceRequestorPHIDType::TYPECONST); - } - - public static function initializeNewRequestor() { - return new NuanceRequestor(); - } - - public function getURI() { - return '/nuance/requestor/view/'.$this->getID().'/'; - } - - public function getPhabricatorUserPHID() { - return idx($this->getData(), 'phabricatorUserPHID'); - } - - public function getActingAsPHID() { - $user_phid = $this->getPhabricatorUserPHID(); - if ($user_phid) { - return $user_phid; - } - - return id(new PhabricatorNuanceApplication())->getPHID(); - } - - public static function newFromPhabricatorUser( - PhabricatorUser $viewer, - PhabricatorContentSource $content_source) { - - // TODO: This is real sketchy and creates a new requestor every time. It - // shouldn't do that. - - $requestor = self::initializeNewRequestor(); - - $xactions = array(); - - $properties = array( - 'phabricatorUserPHID' => $viewer->getPHID(), - ); - - foreach ($properties as $key => $value) { - $xactions[] = id(new NuanceRequestorTransaction()) - ->setTransactionType(NuanceRequestorTransaction::TYPE_PROPERTY) - ->setMetadataValue(NuanceRequestorTransaction::PROPERTY_KEY, $key) - ->setNewValue($value); - } - - $editor = id(new NuanceRequestorEditor()) - ->setActor($viewer) - ->setContentSource($content_source); - - $editor->applyTransactions($requestor, $xactions); - - return $requestor; - } - - public function getNuanceProperty($key, $default = null) { - return idx($this->data, $key, $default); - } - - public function setNuanceProperty($key, $value) { - $this->data[$key] = $value; - return $this; - } - - -/* -( PhabricatorPolicyInterface )----------------------------------------- */ - - - public function getCapabilities() { - return array( - PhabricatorPolicyCapability::CAN_VIEW, - PhabricatorPolicyCapability::CAN_EDIT, - ); - } - - public function getPolicy($capability) { - switch ($capability) { - case PhabricatorPolicyCapability::CAN_VIEW: - return PhabricatorPolicies::POLICY_USER; - case PhabricatorPolicyCapability::CAN_EDIT: - return PhabricatorPolicies::POLICY_USER; - } - } - - public function hasAutomaticCapability($capability, PhabricatorUser $viewer) { - return false; - } - - public function describeAutomaticCapability($capability) { - return null; - } - - -/* -( PhabricatorApplicationTransactionInterface )------------------------- */ - - - public function getApplicationTransactionEditor() { - return new NuanceRequestorEditor(); - } - - public function getApplicationTransactionObject() { - return $this; - } - - public function getApplicationTransactionTemplate() { - return new NuanceRequestorTransaction(); - } - - public function willRenderTimeline( - PhabricatorApplicationTransactionView $timeline, - AphrontRequest $request) { - - return $timeline; - } - -} diff --git a/src/applications/nuance/storage/NuanceRequestorSource.php b/src/applications/nuance/storage/NuanceRequestorSource.php deleted file mode 100644 index bc31fdb6a1..0000000000 --- a/src/applications/nuance/storage/NuanceRequestorSource.php +++ /dev/null @@ -1,34 +0,0 @@ - array( - 'data' => self::SERIALIZATION_JSON, - ), - self::CONFIG_COLUMN_SCHEMA => array( - 'sourceKey' => 'text128', - ), - self::CONFIG_KEY_SCHEMA => array( - 'key_source_key' => array( - 'columns' => array('sourcePHID', 'sourceKey'), - 'unique' => true, - ), - 'key_requestor' => array( - 'columns' => array('requestorPHID', 'id'), - ), - 'key_source' => array( - 'columns' => array('sourcePHID', 'id'), - ), - ), - ) + parent::getConfiguration(); - } - -} diff --git a/src/applications/nuance/storage/NuanceRequestorTransaction.php b/src/applications/nuance/storage/NuanceRequestorTransaction.php deleted file mode 100644 index ae2e0a119f..0000000000 --- a/src/applications/nuance/storage/NuanceRequestorTransaction.php +++ /dev/null @@ -1,17 +0,0 @@ - Date: Tue, 29 Mar 2016 10:31:09 -0700 Subject: [PATCH 21/42] Fix translation of badge feed stories. Summary: Fixes T10688 Test Plan: Award badge, view main Feed Reviewers: chad, #blessed_reviewers, epriestley Reviewed By: chad, #blessed_reviewers Subscribers: Korvin Maniphest Tasks: T10688 Differential Revision: https://secure.phabricator.com/D15547 --- .../translation/PhabricatorUSEnglishTranslation.php | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/infrastructure/internationalization/translation/PhabricatorUSEnglishTranslation.php b/src/infrastructure/internationalization/translation/PhabricatorUSEnglishTranslation.php index 492d68dd1b..c49069fcae 100644 --- a/src/infrastructure/internationalization/translation/PhabricatorUSEnglishTranslation.php +++ b/src/infrastructure/internationalization/translation/PhabricatorUSEnglishTranslation.php @@ -1545,15 +1545,19 @@ final class PhabricatorUSEnglishTranslation '%s awarded %s to %s recipient(s): %s.' => array( array( - '%s awarded %s to recipient: %4$s.', - '%s awarded %s to recipients: %4$s.', + array( + '%s awarded %s to recipient: %4$s.', + '%s awarded %s to recipients: %4$s.', + ), ), ), '%s revoked %s from %s recipient(s): %s.' => array( array( - '%s revoked %s from recipient: %4$s.', - '%s revoked %s from recipients: %4$s.', + array( + '%s revoked %s from recipient: %4$s.', + '%s revoked %s from recipients: %4$s.', + ), ), ), ); From 82f97b6b339aff261cc30c39261f77ea1b7212ed Mon Sep 17 00:00:00 2001 From: Chad Little Date: Tue, 29 Mar 2016 20:01:16 -0700 Subject: [PATCH 22/42] Fix run-on "pre" on project/profile feeds Summary: Because we layout profile navs with display: table-cell, it has unintended consequences with overflowing text boxes, like with `pre`. This causes the layouts to break, like a table might, with long content. For now, let's just line-wrap the `pre` like a terminal would. Test Plan: ```"/opt/ghc-7.10.1-i386/bin/ghc" -hisuf hi -osuf o -hcsuf hc -static -H32m -O -Wall -package-db libraries/bootstrapping.conf -this-package-key ghc-7.11 -hide-all-packages -i -icompiler/backpack -icompiler/basicTypes -icompiler/cmm -icompiler/codeGen -icompiler/coreSyn -icompiler/deSugar -icompiler/ghci -icompiler/hsSyn -icompiler/iface -icompiler/llvmGen -icompiler/main -icompiler/nativeGen -icompiler/parser -icompiler/prelude -icompiler/profiling -icompiler/rename -icompiler/simplCore -icompiler/simplStg -icompiler/specialise -icompiler/stgSyn -icompiler/stranal -icompiler/typecheck -icompiler/types -icompiler/utils -icompiler/vectorise -icompiler/stage1/build -icompiler/stage1/build/autogen -Icompiler/stage1/build -Icompiler/stage1/build/autogen -Icompiler/. -Icompiler/parser -Icompiler/utils -Icompiler/stage1 -optP-include -optPcompiler/stage1/build/autogen/cabal_macros.h -package-id array-0.5.1.0-29bb26a0797af39b979b99b93e9d62fd -package-id base-4.8.0.0-82f21b46ed153fd6b19071a60f2e7937 -package-id binary-0.7.5.0 -package-id bytestring-0.10.6.0-79779027caa792766a3e8dc3e9cb98de -package-id containers-0.5.6.2-90712e174b339b5587c1656969878fb0 -package-id directory-1.2.2.0-73de5f636b1ca4c49aef15924617292c -package-id filepath-1.4.0.0-129f3fdd2b5de4f823a2641d7cf29327 -package-id ghc-boot-0.0.0.0 -package-id hoopl-3.10.2.0 -package-id hpc-0.6.0.2 -package-id process-1.2.3.0-77cd256a28bb4c7cc8cecb076a8fbc37 -package-id template-haskell-2.11.0.0 -package-id time-1.5.0.1-f5db9cf4a7dcb8716611e730437a1fd6 -package-id transformers-0.4.3.0 -package-id unix-2.7.1.0-57629c7ceba7cbcf210cc85471e45e07 -Wall -fno-warn-name-shadowing -this-package-key ghc -XHaskell2010 -DSTAGE=1 -Rghc-timing -fwarn-tabs -no-user-package-db -rtsopts -odir compiler/stage1/build -hidir compiler/stage1/build -stubdir compiler/stage1/build -c compiler/utils/Outputable.hs -o compiler/stage1/build/Outputable.o``` Reviewers: epriestley Reviewed By: epriestley Subscribers: Korvin Differential Revision: https://secure.phabricator.com/D15548 --- resources/celerity/map.php | 4 ++-- webroot/rsrc/css/application/project/project-view.css | 4 ++++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/resources/celerity/map.php b/resources/celerity/map.php index e8c312151e..de2d9a9c28 100644 --- a/resources/celerity/map.php +++ b/resources/celerity/map.php @@ -94,7 +94,7 @@ return array( 'rsrc/css/application/policy/policy.css' => '957ea14c', 'rsrc/css/application/ponder/ponder-view.css' => 'fbd45f96', 'rsrc/css/application/project/project-card-view.css' => '9418c97d', - 'rsrc/css/application/project/project-view.css' => '9ce99f21', + 'rsrc/css/application/project/project-view.css' => 'cbaa10a1', 'rsrc/css/application/releeph/releeph-core.css' => '9b3c5733', 'rsrc/css/application/releeph/releeph-preview-branch.css' => 'b7a6f4a5', 'rsrc/css/application/releeph/releeph-request-differential-create-dialog.css' => '8d8b92cd', @@ -862,7 +862,7 @@ return array( 'policy-transaction-detail-css' => '82100a43', 'ponder-view-css' => 'fbd45f96', 'project-card-view-css' => '9418c97d', - 'project-view-css' => '9ce99f21', + 'project-view-css' => 'cbaa10a1', 'releeph-core' => '9b3c5733', 'releeph-preview-branch' => 'b7a6f4a5', 'releeph-request-differential-create-dialog' => '8d8b92cd', diff --git a/webroot/rsrc/css/application/project/project-view.css b/webroot/rsrc/css/application/project/project-view.css index 2c0fd7d6d8..0af3ef3490 100644 --- a/webroot/rsrc/css/application/project/project-view.css +++ b/webroot/rsrc/css/application/project/project-view.css @@ -91,3 +91,7 @@ .profile-no-badges { padding: 24px 0; } + +.project-view-home .phabricator-remarkup .remarkup-code-block pre { + white-space: pre-wrap; +} From 0ea738f18fd2e06da3161baae85027bee94bf098 Mon Sep 17 00:00:00 2001 From: lkassianik Date: Mon, 28 Mar 2016 15:07:56 -0700 Subject: [PATCH 23/42] Changing criteria for showing badges in object timeline view Summary: Ref T8941 Test Plan: Create an object and create multiple transactions, some time apart to ensure that time clumping isn't interfering. Make sure that events that are large enough to have a dropdown menu show badges under author pic. Reviewers: epriestley, #blessed_reviewers Reviewed By: epriestley, #blessed_reviewers Subscribers: Korvin Maniphest Tasks: T8941 Differential Revision: https://secure.phabricator.com/D15543 --- src/view/phui/PHUITimelineEventView.php | 5 ++++- src/view/phui/PHUITimelineView.php | 8 ++------ 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/view/phui/PHUITimelineEventView.php b/src/view/phui/PHUITimelineEventView.php index 4da2bfe928..08b6cc2aaf 100644 --- a/src/view/phui/PHUITimelineEventView.php +++ b/src/view/phui/PHUITimelineEventView.php @@ -342,6 +342,8 @@ final class PHUITimelineEventView extends AphrontView { // Render "extra" information (timestamp, etc). $extra = $this->renderExtra($events); + $show_badges = false; + $group_titles = array(); $group_items = array(); $group_children = array(); @@ -358,6 +360,7 @@ final class PHUITimelineEventView extends AphrontView { if ($event->hasChildren()) { $group_children[] = $event->renderChildren(); + $show_badges = true; } } @@ -382,7 +385,7 @@ final class PHUITimelineEventView extends AphrontView { 'href' => $this->userHandle->getURI(), ), ''); - if ($this->badges) { + if ($this->badges && $show_badges) { $flex = new PHUIBadgeBoxView(); $flex->addItems($this->badges); $flex->setCollapsed(true); diff --git a/src/view/phui/PHUITimelineView.php b/src/view/phui/PHUITimelineView.php index 729320ebd1..fa3bd4a69f 100644 --- a/src/view/phui/PHUITimelineView.php +++ b/src/view/phui/PHUITimelineView.php @@ -224,12 +224,6 @@ final class PHUITimelineView extends AphrontView { $user_phids = array(); foreach ($events as $key => $event) { - if (!$event->hasChildren()) { - // This is a minor event, so we don't have space to show badges. - unset($events[$key]); - continue; - } - $author_phid = $event->getAuthorPHID(); if (!$author_phid) { unset($events[$key]); @@ -259,7 +253,9 @@ final class PHUITimelineView extends AphrontView { $awards = mgroup($awards, 'getRecipientPHID'); foreach ($events as $event) { + $author_awards = idx($awards, $event->getAuthorPHID(), array()); + $badges = array(); foreach ($author_awards as $award) { $badge = $award->getBadge(); From d9bb66f610db421fe14c4402d81f52c58ef81e7b Mon Sep 17 00:00:00 2001 From: Chad Little Date: Wed, 30 Mar 2016 12:41:32 -0700 Subject: [PATCH 24/42] Update Differential edit pages to new UI Summary: Updates using PHUITwoColumnView, new headers, etc. Test Plan: New Diff, Update Diff, View Standalone pages, Edit pages. Reviewers: epriestley Reviewed By: epriestley Subscribers: Korvin Differential Revision: https://secure.phabricator.com/D15549 --- .../DifferentialChangesetViewController.php | 23 +++++++++------ .../DifferentialDiffCreateController.php | 29 ++++++++++++------- .../DifferentialRevisionEditController.php | 27 +++++++++++------ 3 files changed, 50 insertions(+), 29 deletions(-) diff --git a/src/applications/differential/controller/DifferentialChangesetViewController.php b/src/applications/differential/controller/DifferentialChangesetViewController.php index 01bdd395a7..ff0da2f821 100644 --- a/src/applications/differential/controller/DifferentialChangesetViewController.php +++ b/src/applications/differential/controller/DifferentialChangesetViewController.php @@ -275,6 +275,7 @@ final class DifferentialChangesetViewController extends DifferentialController { ->setRenderURI('/differential/changeset/') ->setDiff($diff) ->setTitle(pht('Standalone View')) + ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) ->setParser($parser); if ($revision_id) { @@ -296,16 +297,20 @@ final class DifferentialChangesetViewController extends DifferentialController { } $crumbs->addTextCrumb($changeset->getDisplayFilename()); + $crumbs->setBorder(true); - return $this->buildApplicationPage( - array( - $crumbs, - $detail, - ), - array( - 'title' => pht('Changeset View'), - 'device' => false, - )); + $header = id(new PHUIHeaderView()) + ->setHeader(pht('Changeset View')) + ->setHeaderIcon('fa-gear'); + + $view = id(new PHUITwoColumnView()) + ->setHeader($header) + ->setFooter($detail); + + return $this->newPage() + ->setTitle(pht('Changeset View')) + ->setCrumbs($crumbs) + ->appendChild($view); } private function buildRawFileResponse( diff --git a/src/applications/differential/controller/DifferentialDiffCreateController.php b/src/applications/differential/controller/DifferentialDiffCreateController.php index 1eb4f88b1a..0e13ea08fd 100644 --- a/src/applications/differential/controller/DifferentialDiffCreateController.php +++ b/src/applications/differential/controller/DifferentialDiffCreateController.php @@ -124,10 +124,12 @@ final class DifferentialDiffCreateController extends DifferentialController { $title = pht('Update Diff'); $header = pht('Update Diff'); $button = pht('Continue'); + $header_icon = 'fa-upload'; } else { $title = pht('Create Diff'); $header = pht('Create New Diff'); $button = pht('Create Diff'); + $header_icon = 'fa-plus-square'; } $form @@ -180,15 +182,12 @@ final class DifferentialDiffCreateController extends DifferentialController { ->setValue($button)); $form_box = id(new PHUIObjectBoxView()) - ->setHeaderText($header) + ->setHeaderText(pht('Diff')) ->setValidationException($validation_exception) ->setForm($form) + ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) ->setFormErrors($errors); - if ($info_view) { - $form_box->setInfoView($info_view); - } - $crumbs = $this->buildApplicationCrumbs(); if ($revision) { $crumbs->addTextCrumb( @@ -196,15 +195,23 @@ final class DifferentialDiffCreateController extends DifferentialController { '/'.$revision->getMonogram()); } $crumbs->addTextCrumb($title); + $crumbs->setBorder(true); - return $this->buildApplicationPage( - array( - $crumbs, + $header = id(new PHUIHeaderView()) + ->setHeader($title) + ->setHeaderIcon($header_icon); + + $view = id(new PHUITwoColumnView()) + ->setHeader($header) + ->setFooter(array( + $info_view, $form_box, - ), - array( - 'title' => $title, )); + + return $this->newPage() + ->setTitle($title) + ->setCrumbs($crumbs) + ->appendChild($view); } } diff --git a/src/applications/differential/controller/DifferentialRevisionEditController.php b/src/applications/differential/controller/DifferentialRevisionEditController.php index a52538ca55..a21e1b2592 100644 --- a/src/applications/differential/controller/DifferentialRevisionEditController.php +++ b/src/applications/differential/controller/DifferentialRevisionEditController.php @@ -171,35 +171,44 @@ final class DifferentialRevisionEditController $crumbs = $this->buildApplicationCrumbs(); if ($revision->getID()) { if ($diff) { + $header_icon = 'fa-upload'; $title = pht('Update Differential Revision'); $crumbs->addTextCrumb( 'D'.$revision->getID(), '/differential/diff/'.$diff->getID().'/'); } else { + $header_icon = 'fa-pencil'; $title = pht('Edit Differential Revision'); $crumbs->addTextCrumb( 'D'.$revision->getID(), '/D'.$revision->getID()); } } else { + $header_icon = 'fa-plus-square'; $title = pht('Create New Differential Revision'); } $form_box = id(new PHUIObjectBoxView()) - ->setHeaderText($title) + ->setHeaderText('Revision') ->setValidationException($validation_exception) + ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) ->setForm($form); $crumbs->addTextCrumb($title); + $crumbs->setBorder(true); - return $this->buildApplicationPage( - array( - $crumbs, - $form_box, - ), - array( - 'title' => $title, - )); + $header = id(new PHUIHeaderView()) + ->setHeader($title) + ->setHeaderIcon($header_icon); + + $view = id(new PHUITwoColumnView()) + ->setHeader($header) + ->setFooter($form_box); + + return $this->newPage() + ->setTitle($title) + ->setCrumbs($crumbs) + ->appendChild($view); } } From 00425cac94d58888ae143f49399a3f11edf185ea Mon Sep 17 00:00:00 2001 From: lkassianik Date: Wed, 30 Mar 2016 17:07:27 -0700 Subject: [PATCH 25/42] Converting badge quality property from color to an integer representation for later sorting purposes Summary: Ref T9007 Test Plan: Create badges, update quality, search by quality without change of functionality. Reviewers: epriestley, #blessed_reviewers Reviewed By: epriestley, #blessed_reviewers Subscribers: Korvin Maniphest Tasks: T9007 Differential Revision: https://secure.phabricator.com/D15551 --- .../20160330.badges.migratequality.sql | 32 ++++++++ .../20160330.badges.qualityxaction.mig.sql | 59 ++++++++++++++ src/__phutil_library_map__.php | 2 + .../constants/PhabricatorBadgesQuality.php | 78 +++++++++++++++++++ .../PhabricatorBadgesViewController.php | 5 +- .../editor/PhabricatorBadgesEditEngine.php | 2 +- .../badges/editor/PhabricatorBadgesEditor.php | 3 +- .../query/PhabricatorBadgesSearchEngine.php | 9 +-- .../badges/storage/PhabricatorBadgesBadge.php | 25 +----- .../storage/PhabricatorBadgesTransaction.php | 5 +- src/view/phui/PHUIBadgeMiniView.php | 4 +- src/view/phui/PHUIBadgeView.php | 43 +++------- 12 files changed, 199 insertions(+), 68 deletions(-) create mode 100644 resources/sql/autopatches/20160330.badges.migratequality.sql create mode 100644 resources/sql/autopatches/20160330.badges.qualityxaction.mig.sql create mode 100644 src/applications/badges/constants/PhabricatorBadgesQuality.php diff --git a/resources/sql/autopatches/20160330.badges.migratequality.sql b/resources/sql/autopatches/20160330.badges.migratequality.sql new file mode 100644 index 0000000000..e86b6df1b8 --- /dev/null +++ b/resources/sql/autopatches/20160330.badges.migratequality.sql @@ -0,0 +1,32 @@ +/* Change quality from color to int */ + +UPDATE {$NAMESPACE}_badges.badges_badge + SET quality = 140 + WHERE quality = 'grey'; + +UPDATE {$NAMESPACE}_badges.badges_badge + SET quality = 120 + WHERE quality = 'white'; + +UPDATE {$NAMESPACE}_badges.badges_badge + SET quality = 100 + WHERE quality = 'green'; + +UPDATE {$NAMESPACE}_badges.badges_badge + SET quality = 80 + WHERE quality = 'blue'; + +UPDATE {$NAMESPACE}_badges.badges_badge + SET quality = 60 + WHERE quality = 'indigo'; + +UPDATE {$NAMESPACE}_badges.badges_badge + SET quality = 40 + WHERE quality = 'orange'; + +UPDATE {$NAMESPACE}_badges.badges_badge + SET quality = 20 + WHERE quality = 'yellow'; + +ALTER TABLE {$NAMESPACE}_badges.badges_badge + MODIFY quality INT UNSIGNED NOT NULL; diff --git a/resources/sql/autopatches/20160330.badges.qualityxaction.mig.sql b/resources/sql/autopatches/20160330.badges.qualityxaction.mig.sql new file mode 100644 index 0000000000..3079618f85 --- /dev/null +++ b/resources/sql/autopatches/20160330.badges.qualityxaction.mig.sql @@ -0,0 +1,59 @@ +/* Migrate old badge quality transactions */ + +UPDATE {$NAMESPACE}_badges.badges_transaction + SET oldValue = 140 + WHERE oldValue = '"grey"' AND transactionType = 'badges:quality'; + +UPDATE {$NAMESPACE}_badges.badges_transaction + SET oldValue = 120 + WHERE oldValue = '"white"' AND transactionType = 'badges:quality'; + +UPDATE {$NAMESPACE}_badges.badges_transaction + SET oldValue = 100 + WHERE oldValue = '"green"' AND transactionType = 'badges:quality'; + +UPDATE {$NAMESPACE}_badges.badges_transaction + SET oldValue = 80 + WHERE oldValue = '"blue"' AND transactionType = 'badges:quality'; + +UPDATE {$NAMESPACE}_badges.badges_transaction + SET oldValue = 60 + WHERE oldValue = '"indigo"' AND transactionType = 'badges:quality'; + +UPDATE {$NAMESPACE}_badges.badges_transaction + SET oldValue = 40 + WHERE oldValue = '"orange"' AND transactionType = 'badges:quality'; + +UPDATE {$NAMESPACE}_badges.badges_transaction + SET oldValue = 20 + WHERE oldValue = '"yellow"' AND transactionType = 'badges:quality'; + + + +UPDATE {$NAMESPACE}_badges.badges_transaction + SET newValue = 140 + WHERE newValue = '"grey"' AND transactionType = 'badges:quality'; + +UPDATE {$NAMESPACE}_badges.badges_transaction + SET newValue = 120 + WHERE newValue = '"white"' AND transactionType = 'badges:quality'; + +UPDATE {$NAMESPACE}_badges.badges_transaction + SET newValue = 100 + WHERE newValue = '"green"' AND transactionType = 'badges:quality'; + +UPDATE {$NAMESPACE}_badges.badges_transaction + SET newValue = 80 + WHERE newValue = '"blue"' AND transactionType = 'badges:quality'; + +UPDATE {$NAMESPACE}_badges.badges_transaction + SET newValue = 60 + WHERE newValue = '"indigo"' AND transactionType = 'badges:quality'; + +UPDATE {$NAMESPACE}_badges.badges_transaction + SET newValue = 40 + WHERE newValue = '"orange"' AND transactionType = 'badges:quality'; + +UPDATE {$NAMESPACE}_badges.badges_transaction + SET newValue = 20 + WHERE newValue = '"yellow"' AND transactionType = 'badges:quality'; diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php index 134e2bbcbe..fafa0bdbe0 100644 --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -1880,6 +1880,7 @@ phutil_register_library_map(array( 'PhabricatorBadgesListController' => 'applications/badges/controller/PhabricatorBadgesListController.php', 'PhabricatorBadgesMailReceiver' => 'applications/badges/mail/PhabricatorBadgesMailReceiver.php', 'PhabricatorBadgesPHIDType' => 'applications/badges/phid/PhabricatorBadgesPHIDType.php', + 'PhabricatorBadgesQuality' => 'applications/badges/constants/PhabricatorBadgesQuality.php', 'PhabricatorBadgesQuery' => 'applications/badges/query/PhabricatorBadgesQuery.php', 'PhabricatorBadgesRecipientsListView' => 'applications/badges/view/PhabricatorBadgesRecipientsListView.php', 'PhabricatorBadgesRemoveRecipientsController' => 'applications/badges/controller/PhabricatorBadgesRemoveRecipientsController.php', @@ -6245,6 +6246,7 @@ phutil_register_library_map(array( 'PhabricatorBadgesListController' => 'PhabricatorBadgesController', 'PhabricatorBadgesMailReceiver' => 'PhabricatorObjectMailReceiver', 'PhabricatorBadgesPHIDType' => 'PhabricatorPHIDType', + 'PhabricatorBadgesQuality' => 'Phobject', 'PhabricatorBadgesQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', 'PhabricatorBadgesRecipientsListView' => 'AphrontView', 'PhabricatorBadgesRemoveRecipientsController' => 'PhabricatorBadgesController', diff --git a/src/applications/badges/constants/PhabricatorBadgesQuality.php b/src/applications/badges/constants/PhabricatorBadgesQuality.php new file mode 100644 index 0000000000..8ab7f3b7d9 --- /dev/null +++ b/src/applications/badges/constants/PhabricatorBadgesQuality.php @@ -0,0 +1,78 @@ + array( + 'rarity' => 140, + 'name' => pht('Poor'), + 'color' => 'grey', + ), + self::COMMON => array( + 'rarity' => 120, + 'name' => pht('Common'), + 'color' => 'white', + ), + self::UNCOMMON => array( + 'rarity' => 100, + 'name' => pht('Uncommon'), + 'color' => 'green', + ), + self::RARE => array( + 'rarity' => 80, + 'name' => pht('Rare'), + 'color' => 'blue', + ), + self::EPIC => array( + 'rarity' => 60, + 'name' => pht('Epic'), + 'color' => 'indigo', + ), + self::LEGENDARY => array( + 'rarity' => 40, + 'name' => pht('Legendary'), + 'color' => 'orange', + ), + self::HEIRLOOM => array( + 'rarity' => 20, + 'name' => pht('Heirloom'), + 'color' => 'yellow', + ), + ); + } + + public static function getDropdownQualityMap() { + $map = self::getQualityMap(); + return ipull($map, 'name'); + } +} diff --git a/src/applications/badges/controller/PhabricatorBadgesViewController.php b/src/applications/badges/controller/PhabricatorBadgesViewController.php index 0f3077de0b..3e3d1ffbc6 100644 --- a/src/applications/badges/controller/PhabricatorBadgesViewController.php +++ b/src/applications/badges/controller/PhabricatorBadgesViewController.php @@ -86,11 +86,12 @@ final class PhabricatorBadgesViewController $view = id(new PHUIPropertyListView()) ->setUser($viewer); - $quality = idx($badge->getQualityNameMap(), $badge->getQuality()); + $quality_name = PhabricatorBadgesQuality::getQualityName( + $badge->getQuality()); $view->addProperty( pht('Quality'), - $quality); + $quality_name); $view->addProperty( pht('Icon'), diff --git a/src/applications/badges/editor/PhabricatorBadgesEditEngine.php b/src/applications/badges/editor/PhabricatorBadgesEditEngine.php index 70cdd08d39..28f07a6dad 100644 --- a/src/applications/badges/editor/PhabricatorBadgesEditEngine.php +++ b/src/applications/badges/editor/PhabricatorBadgesEditEngine.php @@ -89,7 +89,7 @@ final class PhabricatorBadgesEditEngine ->setLabel(pht('Quality')) ->setValue($object->getQuality()) ->setTransactionType(PhabricatorBadgesTransaction::TYPE_QUALITY) - ->setOptions($object->getQualityNameMap()), + ->setOptions(PhabricatorBadgesQuality::getDropdownQualityMap()), id(new PhabricatorRemarkupEditField()) ->setKey('description') ->setLabel(pht('Description')) diff --git a/src/applications/badges/editor/PhabricatorBadgesEditor.php b/src/applications/badges/editor/PhabricatorBadgesEditor.php index af3def28c5..c8dc23df3d 100644 --- a/src/applications/badges/editor/PhabricatorBadgesEditor.php +++ b/src/applications/badges/editor/PhabricatorBadgesEditor.php @@ -66,10 +66,11 @@ final class PhabricatorBadgesEditor case PhabricatorBadgesTransaction::TYPE_DESCRIPTION: case PhabricatorBadgesTransaction::TYPE_ICON: case PhabricatorBadgesTransaction::TYPE_STATUS: - case PhabricatorBadgesTransaction::TYPE_QUALITY: case PhabricatorBadgesTransaction::TYPE_AWARD: case PhabricatorBadgesTransaction::TYPE_REVOKE: return $xaction->getNewValue(); + case PhabricatorBadgesTransaction::TYPE_QUALITY: + return (int)$xaction->getNewValue(); } return parent::getCustomTransactionNewValue($object, $xaction); diff --git a/src/applications/badges/query/PhabricatorBadgesSearchEngine.php b/src/applications/badges/query/PhabricatorBadgesSearchEngine.php index 4bad4d2c65..025ad3b53f 100644 --- a/src/applications/badges/query/PhabricatorBadgesSearchEngine.php +++ b/src/applications/badges/query/PhabricatorBadgesSearchEngine.php @@ -34,9 +34,7 @@ final class PhabricatorBadgesSearchEngine id(new PhabricatorSearchCheckboxesField()) ->setKey('qualities') ->setLabel(pht('Quality')) - ->setOptions( - id(new PhabricatorBadgesBadge()) - ->getQualityNameMap()), + ->setOptions(PhabricatorBadgesQuality::getDropdownQualityMap()), id(new PhabricatorSearchCheckboxesField()) ->setKey('statuses') ->setLabel(pht('Status')) @@ -110,8 +108,9 @@ final class PhabricatorBadgesSearchEngine $list = id(new PHUIObjectItemListView()); foreach ($badges as $badge) { + $quality_name = PhabricatorBadgesQuality::getQualityName( + $badge->getQuality()); - $quality = idx($badge->getQualityNameMap(), $badge->getQuality()); $mini_badge = id(new PHUIBadgeMiniView()) ->setHeader($badge->getName()) ->setIcon($badge->getIcon()) @@ -121,7 +120,7 @@ final class PhabricatorBadgesSearchEngine ->setHeader($badge->getName()) ->setBadge($mini_badge) ->setHref('/badges/view/'.$badge->getID().'/') - ->addAttribute($quality) + ->addAttribute($quality_name) ->addAttribute($badge->getFlavor()); if ($badge->isArchived()) { diff --git a/src/applications/badges/storage/PhabricatorBadgesBadge.php b/src/applications/badges/storage/PhabricatorBadgesBadge.php index 2959111dc4..c5b29df09d 100644 --- a/src/applications/badges/storage/PhabricatorBadgesBadge.php +++ b/src/applications/badges/storage/PhabricatorBadgesBadge.php @@ -25,15 +25,6 @@ final class PhabricatorBadgesBadge extends PhabricatorBadgesDAO const STATUS_ARCHIVED = 'closed'; const DEFAULT_ICON = 'fa-star'; - const DEFAULT_QUALITY = 'green'; - - const POOR = 'grey'; - const COMMON = 'white'; - const UNCOMMON = 'green'; - const RARE = 'blue'; - const EPIC = 'indigo'; - const LEGENDARY = 'orange'; - const HEIRLOOM = 'yellow'; public static function getStatusNameMap() { return array( @@ -42,18 +33,6 @@ final class PhabricatorBadgesBadge extends PhabricatorBadgesDAO ); } - public static function getQualityNameMap() { - return array( - self::POOR => pht('Poor'), - self::COMMON => pht('Common'), - self::UNCOMMON => pht('Uncommon'), - self::RARE => pht('Rare'), - self::EPIC => pht('Epic'), - self::LEGENDARY => pht('Legendary'), - self::HEIRLOOM => pht('Heirloom'), - ); - } - public static function initializeNewBadge(PhabricatorUser $actor) { $app = id(new PhabricatorApplicationQuery()) ->setViewer($actor) @@ -67,7 +46,7 @@ final class PhabricatorBadgesBadge extends PhabricatorBadgesDAO return id(new PhabricatorBadgesBadge()) ->setIcon(self::DEFAULT_ICON) - ->setQuality(self::DEFAULT_QUALITY) + ->setQuality(PhabricatorBadgesQuality::DEFAULT_QUALITY) ->setCreatorPHID($actor->getPHID()) ->setEditPolicy($edit_policy) ->setStatus(self::STATUS_ACTIVE); @@ -81,7 +60,7 @@ final class PhabricatorBadgesBadge extends PhabricatorBadgesDAO 'flavor' => 'text255', 'description' => 'text', 'icon' => 'text255', - 'quality' => 'text255', + 'quality' => 'uint32', 'status' => 'text32', 'mailKey' => 'bytes20', ), diff --git a/src/applications/badges/storage/PhabricatorBadgesTransaction.php b/src/applications/badges/storage/PhabricatorBadgesTransaction.php index 85c0bdce4a..f088c2d973 100644 --- a/src/applications/badges/storage/PhabricatorBadgesTransaction.php +++ b/src/applications/badges/storage/PhabricatorBadgesTransaction.php @@ -111,9 +111,8 @@ final class PhabricatorBadgesTransaction $this->renderHandleLink($author_phid), $new); } else { - $qual_map = PhabricatorBadgesBadge::getQualityNameMap(); - $qual_new = idx($qual_map, $new, $new); - $qual_old = idx($qual_map, $old, $old); + $qual_new = PhabricatorBadgesQuality::getQualityName($new); + $qual_old = PhabricatorBadgesQuality::getQualityName($old); return pht( '%s updated the quality for this badge from "%s" to "%s".', $this->renderHandleLink($author_phid), diff --git a/src/view/phui/PHUIBadgeMiniView.php b/src/view/phui/PHUIBadgeMiniView.php index 21f455b4d6..4e058ed29d 100644 --- a/src/view/phui/PHUIBadgeMiniView.php +++ b/src/view/phui/PHUIBadgeMiniView.php @@ -48,7 +48,9 @@ final class PHUIBadgeMiniView extends AphrontTagView { $classes = array(); $classes[] = 'phui-badge-mini'; if ($this->quality) { - $classes[] = 'phui-badge-mini-'.$this->quality; + $quality_color = PhabricatorBadgesQuality::getQualityColor( + $this->quality); + $classes[] = 'phui-badge-mini-'.$quality_color; } return array( diff --git a/src/view/phui/PHUIBadgeView.php b/src/view/phui/PHUIBadgeView.php index 7e9f310843..7594b6cb30 100644 --- a/src/view/phui/PHUIBadgeView.php +++ b/src/view/phui/PHUIBadgeView.php @@ -10,16 +10,6 @@ final class PHUIBadgeView extends AphrontTagView { private $subhead; private $bylines = array(); - // Yes, World of Warcraft Item Quality - const POOR = 'grey'; - const COMMON = 'white'; - const UNCOMMON = 'green'; - const RARE = 'blue'; - const EPIC = 'indigo'; - const LEGENDARY = 'orange'; - const HEIRLOOM = 'yellow'; - - public function setIcon($icon) { $this->icon = $icon; return $this; @@ -35,6 +25,14 @@ final class PHUIBadgeView extends AphrontTagView { return $this; } + private function getQualityColor() { + return PhabricatorBadgesQuality::getQualityColor($this->quality); + } + + private function getQualityName() { + return PhabricatorBadgesQuality::getQualityName($this->quality); + } + public function setSource($source) { $this->source = $source; return $this; @@ -55,26 +53,6 @@ final class PHUIBadgeView extends AphrontTagView { return $this; } - private function getQualityTitle() { - - switch ($this->quality) { - case self::POOR: - return pht('Poor'); - case self::COMMON: - return pht('Common'); - case self::UNCOMMON: - return pht('Uncommon'); - case self::RARE: - return pht('Rare'); - case self::EPIC: - return pht('Epic'); - case self::LEGENDARY: - return pht('Legendary'); - case self::HEIRLOOM: - return pht('Heirloom'); - } - } - protected function getTagName() { return 'span'; } @@ -86,7 +64,8 @@ final class PHUIBadgeView extends AphrontTagView { $classes = array(); $classes[] = 'phui-badge-view'; if ($this->quality) { - $classes[] = 'phui-badge-view-'.$this->quality; + $color = $this->getQualityColor(); + $classes[] = 'phui-badge-view-'.$color; } return array( @@ -131,7 +110,7 @@ final class PHUIBadgeView extends AphrontTagView { ), array($header, $subhead)); - $quality = phutil_tag_div('phui-badge-quality', $this->getQualityTitle()); + $quality = phutil_tag_div('phui-badge-quality', $this->getQualityName()); $source = phutil_tag_div('phui-badge-source', $this->source); $bylines = array(); From 2386705873bdd56030c2c8c6dd479a31e0b6690d Mon Sep 17 00:00:00 2001 From: Chad Little Date: Thu, 31 Mar 2016 20:39:06 +0000 Subject: [PATCH 26/42] Allow awarding Badges from the profile Summary: [WIP] Allows awarding a badge from a user profile. Unsure of the interactions here if a user can't award any badges, or if we should just hide this. Fixes T10688 Fixes T10318 Test Plan: Award some badges. Steal them back. Reviewers: lpriestley, epriestley Reviewed By: epriestley Subscribers: Korvin Maniphest Tasks: T10318, T10688 Differential Revision: https://secure.phabricator.com/D15544 --- src/__phutil_library_map__.php | 2 + .../PhabricatorBadgesApplication.php | 2 + .../PhabricatorBadgesAwardController.php | 85 +++++++++++++++++++ ...PhabricatorPeopleProfileViewController.php | 34 +++++++- 4 files changed, 122 insertions(+), 1 deletion(-) create mode 100644 src/applications/badges/controller/PhabricatorBadgesAwardController.php diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php index fafa0bdbe0..a718c4edfc 100644 --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -1865,6 +1865,7 @@ phutil_register_library_map(array( 'PhabricatorBadgesApplication' => 'applications/badges/application/PhabricatorBadgesApplication.php', 'PhabricatorBadgesArchiveController' => 'applications/badges/controller/PhabricatorBadgesArchiveController.php', 'PhabricatorBadgesAward' => 'applications/badges/storage/PhabricatorBadgesAward.php', + 'PhabricatorBadgesAwardController' => 'applications/badges/controller/PhabricatorBadgesAwardController.php', 'PhabricatorBadgesAwardQuery' => 'applications/badges/query/PhabricatorBadgesAwardQuery.php', 'PhabricatorBadgesBadge' => 'applications/badges/storage/PhabricatorBadgesBadge.php', 'PhabricatorBadgesCommentController' => 'applications/badges/controller/PhabricatorBadgesCommentController.php', @@ -6223,6 +6224,7 @@ phutil_register_library_map(array( 'PhabricatorDestructibleInterface', 'PhabricatorPolicyInterface', ), + 'PhabricatorBadgesAwardController' => 'PhabricatorBadgesController', 'PhabricatorBadgesAwardQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', 'PhabricatorBadgesBadge' => array( 'PhabricatorBadgesDAO', diff --git a/src/applications/badges/application/PhabricatorBadgesApplication.php b/src/applications/badges/application/PhabricatorBadgesApplication.php index 887a11833d..0de150ee2d 100644 --- a/src/applications/badges/application/PhabricatorBadgesApplication.php +++ b/src/applications/badges/application/PhabricatorBadgesApplication.php @@ -39,6 +39,8 @@ final class PhabricatorBadgesApplication extends PhabricatorApplication { '/badges/' => array( '(?:query/(?P[^/]+)/)?' => 'PhabricatorBadgesListController', + 'award/(?:(?P\d+)/)?' + => 'PhabricatorBadgesAwardController', 'create/' => 'PhabricatorBadgesEditController', 'comment/(?P[1-9]\d*)/' diff --git a/src/applications/badges/controller/PhabricatorBadgesAwardController.php b/src/applications/badges/controller/PhabricatorBadgesAwardController.php new file mode 100644 index 0000000000..0475dd6277 --- /dev/null +++ b/src/applications/badges/controller/PhabricatorBadgesAwardController.php @@ -0,0 +1,85 @@ +getViewer(); + $id = $request->getURIData('id'); + + $user = id(new PhabricatorPeopleQuery()) + ->setViewer($viewer) + ->withIDs(array($id)) + ->executeOne(); + if (!$user) { + return new Aphront404Response(); + } + + $view_uri = '/p/'.$user->getUsername(); + + if ($request->isFormPost()) { + $xactions = array(); + $badge_phid = $request->getStr('badgePHID'); + $badge = id(new PhabricatorBadgesQuery()) + ->setViewer($viewer) + ->withPHIDs(array($badge_phid)) + ->needRecipients(true) + ->requireCapabilities( + array( + PhabricatorPolicyCapability::CAN_EDIT, + PhabricatorPolicyCapability::CAN_VIEW, + )) + ->executeOne(); + if (!$badge) { + return new Aphront404Response(); + } + $award_phids = array($user->getPHID()); + + $xactions[] = id(new PhabricatorBadgesTransaction()) + ->setTransactionType(PhabricatorBadgesTransaction::TYPE_AWARD) + ->setNewValue($award_phids); + + $editor = id(new PhabricatorBadgesEditor($badge)) + ->setActor($viewer) + ->setContentSourceFromRequest($request) + ->setContinueOnNoEffect(true) + ->setContinueOnMissingFields(true) + ->applyTransactions($badge, $xactions); + + return id(new AphrontRedirectResponse()) + ->setURI($view_uri); + } + + $badges = id(new PhabricatorBadgesQuery()) + ->setViewer($viewer) + ->withStatuses(array( + PhabricatorBadgesBadge::STATUS_ACTIVE, + )) + ->requireCapabilities( + array( + PhabricatorPolicyCapability::CAN_VIEW, + PhabricatorPolicyCapability::CAN_EDIT, + )) + ->execute(); + + $options = mpull($badges, 'getName', 'getPHID'); + asort($options); + + $form = id(new AphrontFormView()) + ->setUser($viewer) + ->appendChild( + id(new AphrontFormSelectControl()) + ->setLabel(pht('Badge')) + ->setName('badgePHID') + ->setOptions($options)); + + $dialog = $this->newDialog() + ->setTitle(pht('Grant Badge')) + ->appendForm($form) + ->addCancelButton($view_uri) + ->addSubmitButton(pht('Award')); + + return $dialog; + } + +} diff --git a/src/applications/people/controller/PhabricatorPeopleProfileViewController.php b/src/applications/people/controller/PhabricatorPeopleProfileViewController.php index 213fc94b0e..cb9c558d5a 100644 --- a/src/applications/people/controller/PhabricatorPeopleProfileViewController.php +++ b/src/applications/people/controller/PhabricatorPeopleProfileViewController.php @@ -211,8 +211,40 @@ final class PhabricatorPeopleProfileViewController ->appendChild($error); } + // Best option? + $badges = id(new PhabricatorBadgesQuery()) + ->setViewer($viewer) + ->withStatuses(array( + PhabricatorBadgesBadge::STATUS_ACTIVE, + )) + ->requireCapabilities( + array( + PhabricatorPolicyCapability::CAN_VIEW, + PhabricatorPolicyCapability::CAN_EDIT, + )) + ->execute(); + + $button = id(new PHUIButtonView()) + ->setTag('a') + ->setIcon('fa-plus') + ->setText(pht('Award')) + ->setWorkflow(true) + ->setHref('/badges/award/'.$user->getID().'/'); + + $can_award = false; + if (count($badges)) { + $can_award = true; + } + + $header = id(new PHUIHeaderView()) + ->setHeader(pht('Badges')); + + if (count($badges)) { + $header->addActionLink($button); + } + $box = id(new PHUIObjectBoxView()) - ->setHeaderText(pht('Badges')) + ->setHeader($header) ->addClass('project-view-badges') ->appendChild($flex) ->setBackground(PHUIObjectBoxView::GREY); From 6bbba1e3151d6ac6135354d0216a98163cb12804 Mon Sep 17 00:00:00 2001 From: Chad Little Date: Thu, 31 Mar 2016 13:45:02 -0700 Subject: [PATCH 27/42] Update Auth for new UI Summary: [WIP] Tossing this up for safety and to read through it. Need to test, update some of the other flows. This updates everything in Auth for new UI and modern conventions. Test Plan: Loooots of random testing, new providers, edit providers, logging out, forgot password... more coming. Reviewers: epriestley Reviewed By: epriestley Subscribers: Korvin Differential Revision: https://secure.phabricator.com/D15550 --- .../PhabricatorAuthConfirmLinkController.php | 13 ++-- .../controller/PhabricatorAuthController.php | 8 +-- .../PhabricatorAuthLinkController.php | 13 ++-- .../PhabricatorAuthLoginController.php | 14 ++-- ...PhabricatorAuthNeedsApprovalController.php | 9 ++- ...bricatorAuthNeedsMultiFactorController.php | 19 +++--- .../PhabricatorAuthRegisterController.php | 27 ++++---- .../PhabricatorAuthStartController.php | 21 +++--- .../PhabricatorDisabledUserController.php | 3 +- .../PhabricatorEmailLoginController.php | 14 ++-- ...PhabricatorEmailVerificationController.php | 14 ++-- .../PhabricatorLogoutController.php | 5 +- .../PhabricatorMustVerifyEmailController.php | 17 ++--- .../config/PhabricatorAuthEditController.php | 66 +++++++++---------- .../config/PhabricatorAuthListController.php | 35 +++++----- .../config/PhabricatorAuthNewController.php | 25 +++++-- ...abricatorAuthProviderConfigTransaction.php | 6 +- 17 files changed, 156 insertions(+), 153 deletions(-) diff --git a/src/applications/auth/controller/PhabricatorAuthConfirmLinkController.php b/src/applications/auth/controller/PhabricatorAuthConfirmLinkController.php index 799a8e691e..664a97885f 100644 --- a/src/applications/auth/controller/PhabricatorAuthConfirmLinkController.php +++ b/src/applications/auth/controller/PhabricatorAuthConfirmLinkController.php @@ -66,15 +66,12 @@ final class PhabricatorAuthConfirmLinkController $crumbs = $this->buildApplicationCrumbs(); $crumbs->addTextCrumb(pht('Confirm Link'), $panel_uri); $crumbs->addTextCrumb($provider->getProviderName()); + $crumbs->setBorder(true); - return $this->buildApplicationPage( - array( - $crumbs, - $dialog, - ), - array( - 'title' => pht('Confirm External Account Link'), - )); + return $this->newPage() + ->setTitle(pht('Confirm External Account Link')) + ->setCrumbs($crumbs) + ->appendChild($dialog); } diff --git a/src/applications/auth/controller/PhabricatorAuthController.php b/src/applications/auth/controller/PhabricatorAuthController.php index 76161e6c77..ca4b89f571 100644 --- a/src/applications/auth/controller/PhabricatorAuthController.php +++ b/src/applications/auth/controller/PhabricatorAuthController.php @@ -7,11 +7,9 @@ abstract class PhabricatorAuthController extends PhabricatorController { $view->setTitle($title); $view->setErrors($messages); - return $this->buildApplicationPage( - $view, - array( - 'title' => $title, - )); + return $this->newPage() + ->setTitle($title) + ->appendChild($view); } diff --git a/src/applications/auth/controller/PhabricatorAuthLinkController.php b/src/applications/auth/controller/PhabricatorAuthLinkController.php index d50bcf1d8a..44176a278e 100644 --- a/src/applications/auth/controller/PhabricatorAuthLinkController.php +++ b/src/applications/auth/controller/PhabricatorAuthLinkController.php @@ -116,15 +116,12 @@ final class PhabricatorAuthLinkController $crumbs = $this->buildApplicationCrumbs(); $crumbs->addTextCrumb(pht('Link Account'), $panel_uri); $crumbs->addTextCrumb($provider->getProviderName($name)); + $crumbs->setBorder(true); - return $this->buildApplicationPage( - array( - $crumbs, - $form, - ), - array( - 'title' => $title, - )); + return $this->newPage() + ->setTitle($title) + ->setCrumbs($crumbs) + ->appendChild($form); } } diff --git a/src/applications/auth/controller/PhabricatorAuthLoginController.php b/src/applications/auth/controller/PhabricatorAuthLoginController.php index be610e223a..b9b2a8d876 100644 --- a/src/applications/auth/controller/PhabricatorAuthLoginController.php +++ b/src/applications/auth/controller/PhabricatorAuthLoginController.php @@ -236,7 +236,6 @@ final class PhabricatorAuthLoginController $content) { $crumbs = $this->buildApplicationCrumbs(); - $crumbs->setBorder(true); if ($this->getRequest()->getUser()->isLoggedIn()) { $crumbs->addTextCrumb(pht('Link Account'), $provider->getSettingsURI()); @@ -245,15 +244,12 @@ final class PhabricatorAuthLoginController } $crumbs->addTextCrumb($provider->getProviderName()); + $crumbs->setBorder(true); - return $this->buildApplicationPage( - array( - $crumbs, - $content, - ), - array( - 'title' => pht('Login'), - )); + return $this->newPage() + ->setTitle(pht('Login')) + ->setCrumbs($crumbs) + ->appendChild($content); } public function buildProviderErrorResponse( diff --git a/src/applications/auth/controller/PhabricatorAuthNeedsApprovalController.php b/src/applications/auth/controller/PhabricatorAuthNeedsApprovalController.php index 0d07470560..ba28816375 100644 --- a/src/applications/auth/controller/PhabricatorAuthNeedsApprovalController.php +++ b/src/applications/auth/controller/PhabricatorAuthNeedsApprovalController.php @@ -28,11 +28,10 @@ final class PhabricatorAuthNeedsApprovalController ->appendChild($wait_for_approval) ->addCancelButton('/', pht('Wait Patiently')); - return $this->buildApplicationPage( - $dialog, - array( - 'title' => pht('Wait For Approval'), - )); + return $this->newPage() + ->setTitle(pht('Wait For Approval')) + ->appendChild($dialog); + } } diff --git a/src/applications/auth/controller/PhabricatorAuthNeedsMultiFactorController.php b/src/applications/auth/controller/PhabricatorAuthNeedsMultiFactorController.php index aaf3864156..f3e2562a1c 100644 --- a/src/applications/auth/controller/PhabricatorAuthNeedsMultiFactorController.php +++ b/src/applications/auth/controller/PhabricatorAuthNeedsMultiFactorController.php @@ -76,15 +76,16 @@ final class PhabricatorAuthNeedsMultiFactorController )); } - return $this->buildApplicationPage( - array( - $crumbs, - $help, - $panel, - ), - array( - 'title' => pht('Add Multi-Factor Authentication'), - )); + $view = array( + $help, + $panel, + ); + + return $this->newPage() + ->setTitle(pht('Add Multi-Factor Authentication')) + ->setCrumbs($crumbs) + ->appendChild($view); + } } diff --git a/src/applications/auth/controller/PhabricatorAuthRegisterController.php b/src/applications/auth/controller/PhabricatorAuthRegisterController.php index 655f63acb9..27d54e4ad6 100644 --- a/src/applications/auth/controller/PhabricatorAuthRegisterController.php +++ b/src/applications/auth/controller/PhabricatorAuthRegisterController.php @@ -497,6 +497,7 @@ final class PhabricatorAuthRegisterController $crumbs->addTextCrumb($provider->getProviderName()); $title = pht('Phabricator Registration'); } + $crumbs->setBorder(true); $welcome_view = null; if ($is_setup) { @@ -511,7 +512,6 @@ final class PhabricatorAuthRegisterController } $object_box = id(new PHUIObjectBoxView()) - ->setHeaderText($title) ->setForm($form) ->setFormErrors($errors); @@ -520,16 +520,21 @@ final class PhabricatorAuthRegisterController $invite_header = $this->renderInviteHeader($invite); } - return $this->buildApplicationPage( - array( - $crumbs, - $welcome_view, - $invite_header, - $object_box, - ), - array( - 'title' => $title, - )); + $header = id(new PHUIHeaderView()) + ->setHeader($title); + + $view = id(new PHUITwoColumnView()) + ->setHeader($header) + ->setFooter(array( + $welcome_view, + $invite_header, + $object_box, + )); + + return $this->newPage() + ->setTitle($title) + ->setCrumbs($crumbs) + ->appendChild($view); } private function loadDefaultAccount() { diff --git a/src/applications/auth/controller/PhabricatorAuthStartController.php b/src/applications/auth/controller/PhabricatorAuthStartController.php index 8f4a374241..d591b6313f 100644 --- a/src/applications/auth/controller/PhabricatorAuthStartController.php +++ b/src/applications/auth/controller/PhabricatorAuthStartController.php @@ -189,16 +189,17 @@ final class PhabricatorAuthStartController $crumbs->addTextCrumb(pht('Login')); $crumbs->setBorder(true); - return $this->buildApplicationPage( - array( - $crumbs, - $header, - $invite_message, - $out, - ), - array( - 'title' => pht('Login to Phabricator'), - )); + $title = pht('Login to Phabricator'); + $view = array( + $header, + $invite_message, + $out, + ); + + return $this->newPage() + ->setTitle($title) + ->setCrumbs($crumbs) + ->appendChild($view); } diff --git a/src/applications/auth/controller/PhabricatorDisabledUserController.php b/src/applications/auth/controller/PhabricatorDisabledUserController.php index 39e390d44a..26163c3034 100644 --- a/src/applications/auth/controller/PhabricatorDisabledUserController.php +++ b/src/applications/auth/controller/PhabricatorDisabledUserController.php @@ -15,8 +15,7 @@ final class PhabricatorDisabledUserController return new Aphront404Response(); } - return id(new AphrontDialogView()) - ->setUser($viewer) + return $this->newDialog() ->setTitle(pht('Account Disabled')) ->addCancelButton('/logout/', pht('Okay')) ->appendParagraph(pht('Your account has been disabled.')); diff --git a/src/applications/auth/controller/PhabricatorEmailLoginController.php b/src/applications/auth/controller/PhabricatorEmailLoginController.php index 26609133ea..e9cf693514 100644 --- a/src/applications/auth/controller/PhabricatorEmailLoginController.php +++ b/src/applications/auth/controller/PhabricatorEmailLoginController.php @@ -144,6 +144,7 @@ final class PhabricatorEmailLoginController $crumbs = $this->buildApplicationCrumbs(); $crumbs->addTextCrumb(pht('Reset Password')); + $crumbs->setBorder(true); $dialog = new AphrontDialogView(); $dialog->setUser($request->getUser()); @@ -152,14 +153,11 @@ final class PhabricatorEmailLoginController $dialog->addSubmitButton(pht('Send Email')); $dialog->setSubmitURI('/login/email/'); - return $this->buildApplicationPage( - array( - $crumbs, - $dialog, - ), - array( - 'title' => pht('Forgot Password'), - )); + return $this->newPage() + ->setTitle(pht('Forgot Password')) + ->setCrumbs($crumbs) + ->appendChild($dialog); + } } diff --git a/src/applications/auth/controller/PhabricatorEmailVerificationController.php b/src/applications/auth/controller/PhabricatorEmailVerificationController.php index 83a370139c..e8138339af 100644 --- a/src/applications/auth/controller/PhabricatorEmailVerificationController.php +++ b/src/applications/auth/controller/PhabricatorEmailVerificationController.php @@ -77,15 +77,13 @@ final class PhabricatorEmailVerificationController $crumbs = $this->buildApplicationCrumbs(); $crumbs->addTextCrumb(pht('Verify Email')); + $crumbs->setBorder(true); + + return $this->newPage() + ->setTitle(pht('Verify Email')) + ->setCrumbs($crumbs) + ->appendChild($dialog); - return $this->buildApplicationPage( - array( - $crumbs, - $dialog, - ), - array( - 'title' => pht('Verify Email'), - )); } } diff --git a/src/applications/auth/controller/PhabricatorLogoutController.php b/src/applications/auth/controller/PhabricatorLogoutController.php index de3ac50e5d..2600a08313 100644 --- a/src/applications/auth/controller/PhabricatorLogoutController.php +++ b/src/applications/auth/controller/PhabricatorLogoutController.php @@ -56,14 +56,11 @@ final class PhabricatorLogoutController } if ($viewer->getPHID()) { - $dialog = id(new AphrontDialogView()) - ->setUser($viewer) + return $this->newDialog() ->setTitle(pht('Log out of Phabricator?')) ->appendChild(pht('Are you sure you want to log out?')) ->addSubmitButton(pht('Logout')) ->addCancelButton('/'); - - return id(new AphrontDialogResponse())->setDialog($dialog); } return id(new AphrontRedirectResponse())->setURI('/'); diff --git a/src/applications/auth/controller/PhabricatorMustVerifyEmailController.php b/src/applications/auth/controller/PhabricatorMustVerifyEmailController.php index 779196382d..a944a5b5c8 100644 --- a/src/applications/auth/controller/PhabricatorMustVerifyEmailController.php +++ b/src/applications/auth/controller/PhabricatorMustVerifyEmailController.php @@ -53,14 +53,15 @@ final class PhabricatorMustVerifyEmailController ->appendParagraph($send_again) ->addSubmitButton(pht('Send Another Email')); - return $this->buildApplicationPage( - array( - $sent, - $dialog, - ), - array( - 'title' => pht('Must Verify Email'), - )); + $view = array( + $sent, + $dialog, + ); + + return $this->newPage() + ->setTitle(pht('Must Verify Email')) + ->appendChild($view); + } } diff --git a/src/applications/auth/controller/config/PhabricatorAuthEditController.php b/src/applications/auth/controller/config/PhabricatorAuthEditController.php index 21ba6ef99a..049edfacef 100644 --- a/src/applications/auth/controller/config/PhabricatorAuthEditController.php +++ b/src/applications/auth/controller/config/PhabricatorAuthEditController.php @@ -176,15 +176,33 @@ final class PhabricatorAuthEditController $button = pht('Add Provider'); } $crumb = pht('Add Provider'); - $title = pht('Add Authentication Provider'); + $title = pht('Add Auth Provider'); + $header_icon = 'fa-plus-square'; $cancel_uri = $this->getApplicationURI('/config/new/'); } else { $button = pht('Save'); $crumb = pht('Edit Provider'); - $title = pht('Edit Authentication Provider'); + $title = pht('Edit Auth Provider'); + $header_icon = 'fa-pencil'; $cancel_uri = $this->getApplicationURI(); } + $header = id(new PHUIHeaderView()) + ->setHeader(pht('%s: %s', $title, $provider->getProviderName())) + ->setHeaderIcon($header_icon); + + if ($config->getIsEnabled()) { + $status_name = pht('Enabled'); + $status_color = 'green'; + $status_icon = 'fa-check'; + $header->setStatus($status_icon, $status_color, $status_name); + } else if (!$is_new) { + $status_name = pht('Disabled'); + $status_color = 'indigo'; + $status_icon = 'fa-ban'; + $header->setStatus($status_icon, $status_color, $status_name); + } + $config_name = 'auth.email-domains'; $config_href = '/config/edit/'.$config_name.'/'; @@ -253,32 +271,8 @@ final class PhabricatorAuthEditController 'Phabricator will automatically login with this provider if it is '. 'the only available provider.')); - $status_tag = id(new PHUITagView()) - ->setType(PHUITagView::TYPE_STATE); - if ($is_new) { - $status_tag - ->setName(pht('New Provider')) - ->setBackgroundColor('blue'); - } else if ($config->getIsEnabled()) { - $status_tag - ->setName(pht('Enabled')) - ->setBackgroundColor('green'); - } else { - $status_tag - ->setName(pht('Disabled')) - ->setBackgroundColor('red'); - } - $form = id(new AphrontFormView()) ->setUser($viewer) - ->appendChild( - id(new AphrontFormStaticControl()) - ->setLabel(pht('Provider')) - ->setValue($provider->getProviderName())) - ->appendChild( - id(new AphrontFormStaticControl()) - ->setLabel(pht('Status')) - ->setValue($status_tag)) ->appendChild( id(new AphrontFormCheckboxControl()) ->setLabel(pht('Allow')) @@ -348,6 +342,7 @@ final class PhabricatorAuthEditController $crumbs = $this->buildApplicationCrumbs(); $crumbs->addTextCrumb($crumb); + $crumbs->setBorder(true); $timeline = null; if (!$is_new) { @@ -358,23 +353,28 @@ final class PhabricatorAuthEditController foreach ($xactions as $xaction) { $xaction->setProvider($provider); } + $timeline->setShouldTerminate(true); } $form_box = id(new PHUIObjectBoxView()) - ->setHeaderText($title) + ->setHeaderText(pht('Provider')) ->setFormErrors($errors) + ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) ->setForm($form); - return $this->buildApplicationPage( - array( - $crumbs, + $view = id(new PHUITwoColumnView()) + ->setHeader($header) + ->setFooter(array( $form_box, $footer, $timeline, - ), - array( - 'title' => $title, )); + + return $this->newPage() + ->setTitle($title) + ->setCrumbs($crumbs) + ->appendChild($view); + } } diff --git a/src/applications/auth/controller/config/PhabricatorAuthListController.php b/src/applications/auth/controller/config/PhabricatorAuthListController.php index 6df32f50a5..cb9c21b35f 100644 --- a/src/applications/auth/controller/config/PhabricatorAuthListController.php +++ b/src/applications/auth/controller/config/PhabricatorAuthListController.php @@ -3,9 +3,8 @@ final class PhabricatorAuthListController extends PhabricatorAuthProviderConfigController { - public function processRequest() { - $request = $this->getRequest(); - $viewer = $request->getUser(); + public function handleRequest(AphrontRequest $request) { + $viewer = $this->getViewer(); $configs = id(new PhabricatorAuthProviderConfigQuery()) ->setViewer($viewer) @@ -93,6 +92,7 @@ final class PhabricatorAuthListController $crumbs = $this->buildApplicationCrumbs(); $crumbs->addTextCrumb(pht('Auth Providers')); + $crumbs->setBorder(true); $domains_key = 'auth.email-domains'; $domains_link = $this->renderConfigLink($domains_key); @@ -155,24 +155,29 @@ final class PhabricatorAuthListController ->setDisabled(!$can_manage) ->setText(pht('Add Provider')); - $header = id(new PHUIHeaderView()) - ->setHeader(pht('Authentication Providers')) - ->addActionLink($button); - $list->setFlush(true); $list = id(new PHUIObjectBoxView()) - ->setHeader($header) - ->setInfoView($warning) + ->setHeaderText(pht('Providers')) + ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) ->appendChild($list); - return $this->buildApplicationPage( - array( - $crumbs, + $title = pht('Auth Providers'); + $header = id(new PHUIHeaderView()) + ->setHeader($title) + ->setHeaderIcon('fa-key') + ->addActionLink($button); + + $view = id(new PHUITwoColumnView()) + ->setHeader($header) + ->setFooter(array( + $warning, $list, - ), - array( - 'title' => pht('Authentication Providers'), )); + + return $this->newPage() + ->setTitle($title) + ->setCrumbs($crumbs) + ->appendChild($view); } private function renderConfigLink($key) { diff --git a/src/applications/auth/controller/config/PhabricatorAuthNewController.php b/src/applications/auth/controller/config/PhabricatorAuthNewController.php index 18b4429ea9..dbd43f9ea8 100644 --- a/src/applications/auth/controller/config/PhabricatorAuthNewController.php +++ b/src/applications/auth/controller/config/PhabricatorAuthNewController.php @@ -80,21 +80,32 @@ final class PhabricatorAuthNewController ->setValue(pht('Continue'))); $form_box = id(new PHUIObjectBoxView()) - ->setHeaderText(pht('Add Authentication Provider')) + ->setHeaderText(pht('Provider')) ->setFormErrors($errors) + ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) ->setForm($form); $crumbs = $this->buildApplicationCrumbs(); $crumbs->addTextCrumb(pht('Add Provider')); + $crumbs->setBorder(true); - return $this->buildApplicationPage( - array( - $crumbs, + $title = pht('Add Auth Provider'); + + $header = id(new PHUIHeaderView()) + ->setHeader($title) + ->setHeaderIcon('fa-plus-square'); + + $view = id(new PHUITwoColumnView()) + ->setHeader($header) + ->setFooter(array( $form_box, - ), - array( - 'title' => pht('Add Authentication Provider'), )); + + return $this->newPage() + ->setTitle($title) + ->setCrumbs($crumbs) + ->appendChild($view); + } } diff --git a/src/applications/auth/storage/PhabricatorAuthProviderConfigTransaction.php b/src/applications/auth/storage/PhabricatorAuthProviderConfigTransaction.php index 8314b652ce..e1453b4383 100644 --- a/src/applications/auth/storage/PhabricatorAuthProviderConfigTransaction.php +++ b/src/applications/auth/storage/PhabricatorAuthProviderConfigTransaction.php @@ -44,9 +44,9 @@ final class PhabricatorAuthProviderConfigTransaction switch ($this->getTransactionType()) { case self::TYPE_ENABLE: if ($new) { - return 'fa-play'; + return 'fa-check'; } else { - return 'fa-pause'; + return 'fa-ban'; } } @@ -62,7 +62,7 @@ final class PhabricatorAuthProviderConfigTransaction if ($new) { return 'green'; } else { - return 'red'; + return 'indigo'; } } From 59ef3a31d357b08f527594b3585a5007c966f038 Mon Sep 17 00:00:00 2001 From: Chad Little Date: Thu, 31 Mar 2016 14:57:39 -0700 Subject: [PATCH 28/42] Clean up BadgeView a little bit Summary: Uses BLUE_PROPERTY on Recipients box, removes redundent properties since we render the badge itself already. Test Plan: View a badge with and without a description. Reviewers: epriestley Reviewed By: epriestley Subscribers: Korvin Differential Revision: https://secure.phabricator.com/D15553 --- .../PhabricatorBadgesViewController.php | 20 +------------------ .../PhabricatorBadgesRecipientsListView.php | 6 ++++-- 2 files changed, 5 insertions(+), 21 deletions(-) diff --git a/src/applications/badges/controller/PhabricatorBadgesViewController.php b/src/applications/badges/controller/PhabricatorBadgesViewController.php index 3e3d1ffbc6..9b61e10b44 100644 --- a/src/applications/badges/controller/PhabricatorBadgesViewController.php +++ b/src/applications/badges/controller/PhabricatorBadgesViewController.php @@ -70,7 +70,7 @@ final class PhabricatorBadgesViewController $timeline, $add_comment, )) - ->addPropertySection(pht('BADGE DETAILS'), $details); + ->addPropertySection(pht('DESCRIPTION'), $details); return $this->newPage() ->setTitle($title) @@ -86,26 +86,8 @@ final class PhabricatorBadgesViewController $view = id(new PHUIPropertyListView()) ->setUser($viewer); - $quality_name = PhabricatorBadgesQuality::getQualityName( - $badge->getQuality()); - - $view->addProperty( - pht('Quality'), - $quality_name); - - $view->addProperty( - pht('Icon'), - id(new PhabricatorBadgesIconSet()) - ->getIconLabel($badge->getIcon())); - - $view->addProperty( - pht('Flavor'), - $badge->getFlavor()); - $description = $badge->getDescription(); if (strlen($description)) { - $view->addSectionHeader( - pht('Description'), PHUIPropertyListView::ICON_SUMMARY); $view->addTextContent( new PHUIRemarkupView($viewer, $description)); } diff --git a/src/applications/badges/view/PhabricatorBadgesRecipientsListView.php b/src/applications/badges/view/PhabricatorBadgesRecipientsListView.php index 68633a6a29..20fe2a0b3d 100644 --- a/src/applications/badges/view/PhabricatorBadgesRecipientsListView.php +++ b/src/applications/badges/view/PhabricatorBadgesRecipientsListView.php @@ -27,7 +27,8 @@ final class PhabricatorBadgesRecipientsListView extends AphrontView { PhabricatorPolicyCapability::CAN_EDIT); $list = id(new PHUIObjectItemListView()) - ->setNoDataString(pht('This badge does not have any recipients.')); + ->setNoDataString(pht('This badge does not have any recipients.')) + ->setFlush(true); foreach ($handles as $handle) { $remove_uri = '/badges/recipients/'. @@ -51,7 +52,8 @@ final class PhabricatorBadgesRecipientsListView extends AphrontView { } $box = id(new PHUIObjectBoxView()) - ->setHeaderText(pht('Recipients')) + ->setHeaderText(pht('RECIPIENTS')) + ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) ->setObjectList($list); return $box; From dc2dab94bbda62f12461fb673060b26168656b69 Mon Sep 17 00:00:00 2001 From: Chad Little Date: Thu, 31 Mar 2016 15:29:42 -0700 Subject: [PATCH 29/42] Add commenting to Fund Summary: Adds basic commenting to Fund Initiatives. Test Plan: Leave a comment, see comment. Reviewers: epriestley Reviewed By: epriestley Subscribers: Korvin Differential Revision: https://secure.phabricator.com/D15554 --- .../autopatches/20160331.fund.comments.1.sql | 18 ++++++ src/__phutil_library_map__.php | 4 ++ .../PhabricatorFundApplication.php | 1 + .../FundInitiativeCommentController.php | 63 +++++++++++++++++++ .../FundInitiativeViewController.php | 31 ++++++++- .../fund/editor/FundInitiativeEditor.php | 1 + .../storage/FundInitiativeTransaction.php | 2 +- .../FundInitiativeTransactionComment.php | 10 +++ 8 files changed, 127 insertions(+), 3 deletions(-) create mode 100644 resources/sql/autopatches/20160331.fund.comments.1.sql create mode 100644 src/applications/fund/controller/FundInitiativeCommentController.php create mode 100644 src/applications/fund/storage/FundInitiativeTransactionComment.php diff --git a/resources/sql/autopatches/20160331.fund.comments.1.sql b/resources/sql/autopatches/20160331.fund.comments.1.sql new file mode 100644 index 0000000000..a4c1e2b5fa --- /dev/null +++ b/resources/sql/autopatches/20160331.fund.comments.1.sql @@ -0,0 +1,18 @@ +CREATE TABLE {$NAMESPACE}_fund.fund_initiativetransaction_comment ( + id INT UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT, + phid VARCHAR(64) NOT NULL, + transactionPHID VARCHAR(64), + authorPHID VARCHAR(64) NOT NULL, + viewPolicy VARCHAR(64) NOT NULL, + editPolicy VARCHAR(64) NOT NULL, + commentVersion INT UNSIGNED NOT NULL, + content LONGTEXT NOT NULL COLLATE {$COLLATE_TEXT}, + contentSource LONGTEXT NOT NULL COLLATE {$COLLATE_TEXT}, + isDeleted BOOL NOT NULL, + dateCreated INT UNSIGNED NOT NULL, + dateModified INT UNSIGNED NOT NULL, + + UNIQUE KEY `key_phid` (phid), + UNIQUE KEY `key_version` (transactionPHID, commentVersion) + +) ENGINE=InnoDB, COLLATE {$COLLATE_TEXT}; diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php index a718c4edfc..c4bc803f52 100644 --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -1024,6 +1024,7 @@ phutil_register_library_map(array( 'FundInitiative' => 'applications/fund/storage/FundInitiative.php', 'FundInitiativeBackController' => 'applications/fund/controller/FundInitiativeBackController.php', 'FundInitiativeCloseController' => 'applications/fund/controller/FundInitiativeCloseController.php', + 'FundInitiativeCommentController' => 'applications/fund/controller/FundInitiativeCommentController.php', 'FundInitiativeEditController' => 'applications/fund/controller/FundInitiativeEditController.php', 'FundInitiativeEditor' => 'applications/fund/editor/FundInitiativeEditor.php', 'FundInitiativeFulltextEngine' => 'applications/fund/search/FundInitiativeFulltextEngine.php', @@ -1034,6 +1035,7 @@ phutil_register_library_map(array( 'FundInitiativeReplyHandler' => 'applications/fund/mail/FundInitiativeReplyHandler.php', 'FundInitiativeSearchEngine' => 'applications/fund/query/FundInitiativeSearchEngine.php', 'FundInitiativeTransaction' => 'applications/fund/storage/FundInitiativeTransaction.php', + 'FundInitiativeTransactionComment' => 'applications/fund/storage/FundInitiativeTransactionComment.php', 'FundInitiativeTransactionQuery' => 'applications/fund/query/FundInitiativeTransactionQuery.php', 'FundInitiativeViewController' => 'applications/fund/controller/FundInitiativeViewController.php', 'FundSchemaSpec' => 'applications/fund/storage/FundSchemaSpec.php', @@ -5238,6 +5240,7 @@ phutil_register_library_map(array( ), 'FundInitiativeBackController' => 'FundController', 'FundInitiativeCloseController' => 'FundController', + 'FundInitiativeCommentController' => 'FundController', 'FundInitiativeEditController' => 'FundController', 'FundInitiativeEditor' => 'PhabricatorApplicationTransactionEditor', 'FundInitiativeFulltextEngine' => 'PhabricatorFulltextEngine', @@ -5248,6 +5251,7 @@ phutil_register_library_map(array( 'FundInitiativeReplyHandler' => 'PhabricatorApplicationTransactionReplyHandler', 'FundInitiativeSearchEngine' => 'PhabricatorApplicationSearchEngine', 'FundInitiativeTransaction' => 'PhabricatorApplicationTransaction', + 'FundInitiativeTransactionComment' => 'PhabricatorApplicationTransactionComment', 'FundInitiativeTransactionQuery' => 'PhabricatorApplicationTransactionQuery', 'FundInitiativeViewController' => 'FundController', 'FundSchemaSpec' => 'PhabricatorConfigSchemaSpec', diff --git a/src/applications/fund/application/PhabricatorFundApplication.php b/src/applications/fund/application/PhabricatorFundApplication.php index 889baca20e..3a26e501e6 100644 --- a/src/applications/fund/application/PhabricatorFundApplication.php +++ b/src/applications/fund/application/PhabricatorFundApplication.php @@ -42,6 +42,7 @@ final class PhabricatorFundApplication extends PhabricatorApplication { '/fund/' => array( '(?:query/(?P[^/]+)/)?' => 'FundInitiativeListController', 'create/' => 'FundInitiativeEditController', + 'comment/(?P[1-9]\d*)/' => 'FundInitiativeCommentController', 'edit/(?:(?P\d+)/)?' => 'FundInitiativeEditController', 'close/(?P\d+)/' => 'FundInitiativeCloseController', 'back/(?P\d+)/' => 'FundInitiativeBackController', diff --git a/src/applications/fund/controller/FundInitiativeCommentController.php b/src/applications/fund/controller/FundInitiativeCommentController.php new file mode 100644 index 0000000000..2c4998a94c --- /dev/null +++ b/src/applications/fund/controller/FundInitiativeCommentController.php @@ -0,0 +1,63 @@ +getViewer(); + $id = $request->getURIData('id'); + + if (!$request->isFormPost()) { + return new Aphront400Response(); + } + + $initiative = id(new FundInitiativeQuery()) + ->setViewer($viewer) + ->withIDs(array($id)) + ->executeOne(); + if (!$initiative) { + return new Aphront404Response(); + } + + $is_preview = $request->isPreviewRequest(); + $draft = PhabricatorDraft::buildFromRequest($request); + + $view_uri = '/'.$initiative->getMonogram(); + + $xactions = array(); + $xactions[] = id(new FundInitiativeTransaction()) + ->setTransactionType(PhabricatorTransactions::TYPE_COMMENT) + ->attachComment( + id(new FundInitiativeTransactionComment()) + ->setContent($request->getStr('comment'))); + + $editor = id(new FundInitiativeEditor()) + ->setActor($viewer) + ->setContinueOnNoEffect($request->isContinueRequest()) + ->setContentSourceFromRequest($request) + ->setIsPreview($is_preview); + + try { + $xactions = $editor->applyTransactions($initiative, $xactions); + } catch (PhabricatorApplicationTransactionNoEffectException $ex) { + return id(new PhabricatorApplicationTransactionNoEffectResponse()) + ->setCancelURI($view_uri) + ->setException($ex); + } + + if ($draft) { + $draft->replaceOrDelete(); + } + + if ($request->isAjax() && $is_preview) { + return id(new PhabricatorApplicationTransactionResponse()) + ->setViewer($viewer) + ->setTransactions($xactions) + ->setIsPreview($is_preview); + } else { + return id(new AphrontRedirectResponse()) + ->setURI($view_uri); + } + } + +} diff --git a/src/applications/fund/controller/FundInitiativeViewController.php b/src/applications/fund/controller/FundInitiativeViewController.php index a416054ae3..18b123bf3a 100644 --- a/src/applications/fund/controller/FundInitiativeViewController.php +++ b/src/applications/fund/controller/FundInitiativeViewController.php @@ -52,12 +52,16 @@ final class FundInitiativeViewController $timeline = $this->buildTransactionTimeline( $initiative, new FundInitiativeTransactionQuery()); - $timeline->setShouldTerminate(true); + + $add_comment = $this->buildCommentForm($initiative); $view = id(new PHUITwoColumnView()) ->setHeader($header) ->setCurtain($curtain) - ->setMainColumn($timeline) + ->setMainColumn(array( + $timeline, + $add_comment, + )) ->addPropertySection(pht('DETAILS'), $details); return $this->newPage() @@ -160,4 +164,27 @@ final class FundInitiativeViewController return $curtain; } + private function buildCommentForm(FundInitiative $initiative) { + $viewer = $this->getViewer(); + + $is_serious = PhabricatorEnv::getEnvConfig('phabricator.serious-business'); + + $add_comment_header = $is_serious + ? pht('Add Comment') + : pht('Add Liquidity'); + + $draft = PhabricatorDraft::newFromUserAndKey( + $viewer, $initiative->getPHID()); + + return id(new PhabricatorApplicationTransactionCommentView()) + ->setUser($viewer) + ->setObjectPHID($initiative->getPHID()) + ->setDraft($draft) + ->setHeaderText($add_comment_header) + ->setAction( + $this->getApplicationURI('/comment/'.$initiative->getID().'/')) + ->setSubmitButtonName(pht('Add Comment')); + } + + } diff --git a/src/applications/fund/editor/FundInitiativeEditor.php b/src/applications/fund/editor/FundInitiativeEditor.php index fc07c472ba..40fc6f0174 100644 --- a/src/applications/fund/editor/FundInitiativeEditor.php +++ b/src/applications/fund/editor/FundInitiativeEditor.php @@ -23,6 +23,7 @@ final class FundInitiativeEditor $types[] = FundInitiativeTransaction::TYPE_MERCHANT; $types[] = PhabricatorTransactions::TYPE_VIEW_POLICY; $types[] = PhabricatorTransactions::TYPE_EDIT_POLICY; + $types[] = PhabricatorTransactions::TYPE_COMMENT; return $types; } diff --git a/src/applications/fund/storage/FundInitiativeTransaction.php b/src/applications/fund/storage/FundInitiativeTransaction.php index c06d62e229..5c1f8c589d 100644 --- a/src/applications/fund/storage/FundInitiativeTransaction.php +++ b/src/applications/fund/storage/FundInitiativeTransaction.php @@ -27,7 +27,7 @@ final class FundInitiativeTransaction } public function getApplicationTransactionCommentObject() { - return null; + return new FundInitiativeTransactionComment(); } public function getRequiredHandlePHIDs() { diff --git a/src/applications/fund/storage/FundInitiativeTransactionComment.php b/src/applications/fund/storage/FundInitiativeTransactionComment.php new file mode 100644 index 0000000000..3e7330ab2c --- /dev/null +++ b/src/applications/fund/storage/FundInitiativeTransactionComment.php @@ -0,0 +1,10 @@ + Date: Thu, 31 Mar 2016 17:29:32 -0700 Subject: [PATCH 30/42] Clean up EditEngine implementation on Badges Summary: Fixes T10672. Cleaning this up myself since I was responsible for the implementation. Test Plan: Leave a comment, Edit a badge, create a badge. Reviewers: lpriestley, epriestley Reviewed By: epriestley Subscribers: Korvin Maniphest Tasks: T10672 Differential Revision: https://secure.phabricator.com/D15556 --- .../PhabricatorBadgesApplication.php | 4 +-- .../PhabricatorBadgesListController.php | 13 +++------- .../PhabricatorBadgesViewController.php | 26 +++---------------- .../editor/PhabricatorBadgesEditEngine.php | 17 ++++++++++-- 4 files changed, 24 insertions(+), 36 deletions(-) diff --git a/src/applications/badges/application/PhabricatorBadgesApplication.php b/src/applications/badges/application/PhabricatorBadgesApplication.php index 0de150ee2d..5423609fda 100644 --- a/src/applications/badges/application/PhabricatorBadgesApplication.php +++ b/src/applications/badges/application/PhabricatorBadgesApplication.php @@ -45,8 +45,8 @@ final class PhabricatorBadgesApplication extends PhabricatorApplication { => 'PhabricatorBadgesEditController', 'comment/(?P[1-9]\d*)/' => 'PhabricatorBadgesCommentController', - 'edit/(?:(?P\d+)/)?' - => 'PhabricatorBadgesEditController', + $this->getEditRoutePattern('edit/') + => 'PhabricatorBadgesEditController', 'archive/(?:(?P\d+)/)?' => 'PhabricatorBadgesArchiveController', 'view/(?:(?P\d+)/)?' diff --git a/src/applications/badges/controller/PhabricatorBadgesListController.php b/src/applications/badges/controller/PhabricatorBadgesListController.php index c47f38fc5d..5c462e8341 100644 --- a/src/applications/badges/controller/PhabricatorBadgesListController.php +++ b/src/applications/badges/controller/PhabricatorBadgesListController.php @@ -16,16 +16,9 @@ final class PhabricatorBadgesListController protected function buildApplicationCrumbs() { $crumbs = parent::buildApplicationCrumbs(); - $can_create = $this->hasApplicationCapability( - PhabricatorBadgesCreateCapability::CAPABILITY); - - $crumbs->addAction( - id(new PHUIListItemView()) - ->setName(pht('Create Badge')) - ->setHref($this->getApplicationURI('create/')) - ->setIcon('fa-plus-square') - ->setDisabled(!$can_create) - ->setWorkflow(!$can_create)); + id(new PhabricatorBadgesEditEngine()) + ->setViewer($this->getViewer()) + ->addActionToCrumbs($crumbs); return $crumbs; } diff --git a/src/applications/badges/controller/PhabricatorBadgesViewController.php b/src/applications/badges/controller/PhabricatorBadgesViewController.php index 9b61e10b44..4539440588 100644 --- a/src/applications/badges/controller/PhabricatorBadgesViewController.php +++ b/src/applications/badges/controller/PhabricatorBadgesViewController.php @@ -60,7 +60,9 @@ final class PhabricatorBadgesViewController ->setHandles($handles) ->setUser($viewer); - $add_comment = $this->buildCommentForm($badge); + $comment_view = id(new PhabricatorBadgesEditEngine()) + ->setViewer($viewer) + ->buildEditEngineCommentView($badge); $view = id(new PHUITwoColumnView()) ->setHeader($header) @@ -68,7 +70,7 @@ final class PhabricatorBadgesViewController ->setMainColumn(array( $recipient_list, $timeline, - $add_comment, + $comment_view, )) ->addPropertySection(pht('DESCRIPTION'), $details); @@ -154,24 +156,4 @@ final class PhabricatorBadgesViewController return $curtain; } - private function buildCommentForm(PhabricatorBadgesBadge $badge) { - $viewer = $this->getViewer(); - - $is_serious = PhabricatorEnv::getEnvConfig('phabricator.serious-business'); - - $add_comment_header = $is_serious - ? pht('Add Comment') - : pht('Render Honors'); - - $draft = PhabricatorDraft::newFromUserAndKey($viewer, $badge->getPHID()); - - return id(new PhabricatorApplicationTransactionCommentView()) - ->setUser($viewer) - ->setObjectPHID($badge->getPHID()) - ->setDraft($draft) - ->setHeaderText($add_comment_header) - ->setAction($this->getApplicationURI('/comment/'.$badge->getID().'/')) - ->setSubmitButtonName(pht('Add Comment')); - } - } diff --git a/src/applications/badges/editor/PhabricatorBadgesEditEngine.php b/src/applications/badges/editor/PhabricatorBadgesEditEngine.php index 28f07a6dad..8c569b5fbb 100644 --- a/src/applications/badges/editor/PhabricatorBadgesEditEngine.php +++ b/src/applications/badges/editor/PhabricatorBadgesEditEngine.php @@ -49,18 +49,31 @@ final class PhabricatorBadgesEditEngine return pht('Badge'); } + protected function getObjectCreateCancelURI($object) { + return $this->getApplication()->getApplicationURI('/'); + } + + protected function getEditorURI() { + return $this->getApplication()->getApplicationURI('edit/'); + } + protected function getCommentViewHeaderText($object) { - return pht('Add Comment'); + return pht('Render Honors'); } protected function getCommentViewButtonText($object) { - return pht('Submit'); + return pht('Salute'); } protected function getObjectViewURI($object) { return $object->getViewURI(); } + protected function getCreateNewObjectPolicy() { + return $this->getApplication()->getPolicy( + PhabricatorBadgesCreateCapability::CAPABILITY); + } + protected function buildCustomEditFields($object) { return array( From 25c4101349696a9a5964498a9e890e7e40b20754 Mon Sep 17 00:00:00 2001 From: Chad Little Date: Thu, 31 Mar 2016 19:04:08 -0700 Subject: [PATCH 31/42] Convert Slowvote Edit page to new UI Summary: Minor, updates Slowvote editing page to new UI/header Test Plan: Create a poll, edit a poll Reviewers: epriestley Reviewed By: epriestley Subscribers: Korvin Differential Revision: https://secure.phabricator.com/D15557 --- .../PhabricatorSlowvoteEditController.php | 31 ++++++++++--------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/src/applications/slowvote/controller/PhabricatorSlowvoteEditController.php b/src/applications/slowvote/controller/PhabricatorSlowvoteEditController.php index bd6dca4ce3..7354466772 100644 --- a/src/applications/slowvote/controller/PhabricatorSlowvoteEditController.php +++ b/src/applications/slowvote/controller/PhabricatorSlowvoteEditController.php @@ -136,21 +136,10 @@ final class PhabricatorSlowvoteEditController } } - $instructions = - phutil_tag( - 'p', - array( - 'class' => 'aphront-form-instructions', - ), - pht('Resolve issues and build consensus through '. - 'protracted deliberation.')); - $form = id(new AphrontFormView()) ->setUser($viewer) - ->appendChild($instructions) ->appendChild( - id(new AphrontFormTextAreaControl()) - ->setHeight(AphrontFormTextAreaControl::HEIGHT_VERY_SHORT) + id(new AphrontFormTextControl()) ->setLabel(pht('Question')) ->setName('question') ->setValue($v_question) @@ -218,10 +207,12 @@ final class PhabricatorSlowvoteEditController $title = pht('Create Slowvote'); $button = pht('Create'); $cancel_uri = $this->getApplicationURI(); + $header_icon = 'fa-plus-square'; } else { - $title = pht('Edit %s', 'V'.$poll->getID()); + $title = pht('Edit Poll: %s', $poll->getQuestion()); $button = pht('Save Changes'); $cancel_uri = '/V'.$poll->getID(); + $header_icon = 'fa-pencil'; } $policies = id(new PhabricatorPolicyQuery()) @@ -259,18 +250,28 @@ final class PhabricatorSlowvoteEditController $crumbs = $this->buildApplicationCrumbs(); $crumbs->addTextCrumb($title); + $crumbs->setBorder(true); $form_box = id(new PHUIObjectBoxView()) - ->setHeaderText($title) + ->setHeaderText(pht('Poll')) ->setFormErrors($errors) + ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) ->setForm($form); + $header = id(new PHUIHeaderView()) + ->setHeader($title) + ->setHeaderIcon($header_icon); + + $view = id(new PHUITwoColumnView()) + ->setHeader($header) + ->setFooter($form_box); + return $this->newPage() ->setTitle($title) ->setCrumbs($crumbs) ->appendChild( array( - $form_box, + $view, )); } From a22d37f44701611480f2c0bc46de6f7efcc6440a Mon Sep 17 00:00:00 2001 From: Chad Little Date: Fri, 1 Apr 2016 14:13:58 +0000 Subject: [PATCH 32/42] Update Countdown edit page for new UI Summary: Modernizes Countdown edit page Test Plan: New countdown, edit countdown Reviewers: epriestley Reviewed By: epriestley Subscribers: Korvin Differential Revision: https://secure.phabricator.com/D15558 --- .../PhabricatorCountdownEditController.php | 22 ++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/src/applications/countdown/controller/PhabricatorCountdownEditController.php b/src/applications/countdown/controller/PhabricatorCountdownEditController.php index a6cdacc047..ea89c1591b 100644 --- a/src/applications/countdown/controller/PhabricatorCountdownEditController.php +++ b/src/applications/countdown/controller/PhabricatorCountdownEditController.php @@ -8,7 +8,6 @@ final class PhabricatorCountdownEditController $id = $request->getURIData('id'); if ($id) { - $page_title = pht('Edit Countdown'); $countdown = id(new PhabricatorCountdownQuery()) ->setViewer($viewer) ->withIDs(array($id)) @@ -28,8 +27,9 @@ final class PhabricatorCountdownEditController $countdown->getPHID(), PhabricatorProjectObjectHasProjectEdgeType::EDGECONST); $v_projects = array_reverse($v_projects); + $title = pht('Edit Countdown: %s', $countdown->getTitle()); } else { - $page_title = pht('Create Countdown'); + $title = pht('Create Countdown'); $countdown = PhabricatorCountdown::initializeNewCountdown($viewer); $date_value = AphrontFormDateControlValue::newFromEpoch( $viewer, PhabricatorTime::getNow()); @@ -116,6 +116,7 @@ final class PhabricatorCountdownEditController } $crumbs = $this->buildApplicationCrumbs(); + $crumbs->setBorder(true); $cancel_uri = '/countdown/'; if ($countdown->getID()) { @@ -123,9 +124,11 @@ final class PhabricatorCountdownEditController $crumbs->addTextCrumb('C'.$countdown->getID(), $cancel_uri); $crumbs->addTextCrumb(pht('Edit')); $submit_label = pht('Save Changes'); + $header_icon = 'fa-pencil'; } else { $crumbs->addTextCrumb(pht('Create Countdown')); $submit_label = pht('Create Countdown'); + $header_icon = 'fa-plus-square'; } $policies = id(new PhabricatorPolicyQuery()) @@ -180,16 +183,25 @@ final class PhabricatorCountdownEditController ->setValue($submit_label)); $form_box = id(new PHUIObjectBoxView()) - ->setHeaderText($page_title) + ->setHeaderText(pht('Countdown')) ->setFormErrors($errors) + ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) ->setForm($form); + $header = id(new PHUIHeaderView()) + ->setHeader($title) + ->setHeaderIcon($header_icon); + + $view = id(new PHUITwoColumnView()) + ->setHeader($header) + ->setFooter($form_box); + return $this->newPage() - ->setTitle($page_title) + ->setTitle($title) ->setCrumbs($crumbs) ->appendChild( array( - $form_box, + $view, )); } From c40f6e63ca1caeffe80daa07a6e162d01326ff2e Mon Sep 17 00:00:00 2001 From: Chad Little Date: Fri, 1 Apr 2016 14:14:25 +0000 Subject: [PATCH 33/42] Update Herald edit/transcripts to modern UI Summary: Walks through various object, rule, create forms and transcripts in Herald. Slightly nicer looking. Test Plan: Make rules, see rules, edit rules, see transcripts. Reviewers: epriestley Reviewed By: epriestley Subscribers: Korvin Differential Revision: https://secure.phabricator.com/D15559 --- resources/celerity/map.php | 6 ++-- .../herald/controller/HeraldNewController.php | 29 ++++++++++--------- .../controller/HeraldRuleController.php | 20 +++++++++---- .../HeraldTestConsoleController.php | 14 +++++++-- .../controller/HeraldTranscriptController.php | 18 +++++++++--- webroot/rsrc/css/phui/phui-form-view.css | 3 +- 6 files changed, 59 insertions(+), 31 deletions(-) diff --git a/resources/celerity/map.php b/resources/celerity/map.php index de2d9a9c28..a4917e52e6 100644 --- a/resources/celerity/map.php +++ b/resources/celerity/map.php @@ -7,7 +7,7 @@ */ return array( 'names' => array( - 'core.pkg.css' => '26886078', + 'core.pkg.css' => '2d0339fc', 'core.pkg.js' => 'e5484f37', 'darkconsole.pkg.js' => 'e7393ebb', 'differential.pkg.css' => '7ba78475', @@ -133,7 +133,7 @@ return array( 'rsrc/css/phui/phui-document.css' => '9c71d2bf', 'rsrc/css/phui/phui-feed-story.css' => '04aec08f', 'rsrc/css/phui/phui-fontkit.css' => '9cda225e', - 'rsrc/css/phui/phui-form-view.css' => '4a1a0f5e', + 'rsrc/css/phui/phui-form-view.css' => '6a51768e', 'rsrc/css/phui/phui-form.css' => 'aac1d51d', 'rsrc/css/phui/phui-head-thing.css' => 'fd311e5f', 'rsrc/css/phui/phui-header-view.css' => '230254d3', @@ -821,7 +821,7 @@ return array( 'phui-font-icon-base-css' => '6449bce8', 'phui-fontkit-css' => '9cda225e', 'phui-form-css' => 'aac1d51d', - 'phui-form-view-css' => '4a1a0f5e', + 'phui-form-view-css' => '6a51768e', 'phui-head-thing-view-css' => 'fd311e5f', 'phui-header-view-css' => '230254d3', 'phui-hovercard' => '1bd28176', diff --git a/src/applications/herald/controller/HeraldNewController.php b/src/applications/herald/controller/HeraldNewController.php index c25b4c839b..e9fa1e66bd 100644 --- a/src/applications/herald/controller/HeraldNewController.php +++ b/src/applications/herald/controller/HeraldNewController.php @@ -114,6 +114,7 @@ final class HeraldNewController extends HeraldController { $cancel_text = null; $cancel_uri = $this->getApplicationURI(); + $title = pht('Create Herald Rule'); break; case 1: $rule_types = $this->renderRuleTypeControl( @@ -123,14 +124,6 @@ final class HeraldNewController extends HeraldController { $form ->addHiddenInput('content_type', $content_type) ->addHiddenInput('step', 2) - ->appendChild( - id(new AphrontFormStaticControl()) - ->setLabel(pht('Rule for')) - ->setValue( - phutil_tag( - 'strong', - array(), - idx($content_type_map, $content_type)))) ->appendChild($rule_types); $cancel_text = pht('Back'); @@ -141,6 +134,8 @@ final class HeraldNewController extends HeraldController { 'step' => 0, )); $cancel_uri = $this->getApplicationURI($cancel_uri); + $title = pht('Create Herald Rule: %s', + idx($content_type_map, $content_type)); break; case 2: $adapter = HeraldAdapter::getAdapterForContentType($content_type); @@ -187,10 +182,11 @@ final class HeraldNewController extends HeraldController { 'step' => 1, )); $cancel_uri = $this->getApplicationURI($cancel_uri); + $title = pht('Create Herald Rule: %s', + idx($content_type_map, $content_type)); break; } - $form ->appendChild( id(new AphrontFormSubmitControl()) @@ -199,21 +195,28 @@ final class HeraldNewController extends HeraldController { $form_box = id(new PHUIObjectBoxView()) ->setFormErrors($errors) - ->setHeaderText(pht('Create Herald Rule')) + ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) ->setForm($form); $crumbs = $this ->buildApplicationCrumbs() - ->addTextCrumb(pht('Create Rule')); + ->addTextCrumb(pht('Create Rule')) + ->setBorder(true); - $title = pht('Create Herald Rule'); + $header = id(new PHUIHeaderView()) + ->setHeader($title) + ->setHeaderIcon('fa-plus-square'); + + $view = id(new PHUITwoColumnView()) + ->setHeader($header) + ->setFooter($form_box); return $this->newPage() ->setTitle($title) ->setCrumbs($crumbs) ->appendChild( array( - $form_box, + $view, )); } diff --git a/src/applications/herald/controller/HeraldRuleController.php b/src/applications/herald/controller/HeraldRuleController.php index 0289dce2e6..74ce553f9c 100644 --- a/src/applications/herald/controller/HeraldRuleController.php +++ b/src/applications/herald/controller/HeraldRuleController.php @@ -235,26 +235,34 @@ final class HeraldRuleController extends HeraldController { $this->setupEditorBehavior($rule, $handles, $adapter); $title = $rule->getID() - ? pht('Edit Herald Rule') - : pht('Create Herald Rule'); + ? pht('Edit Herald Rule: %s', $rule->getName()) + : pht('Create Herald Rule: %s', idx($content_type_map, $content_type)); + + $icon = $rule->getID() ? 'fa-pencil' : 'fa-plus-square'; $form_box = id(new PHUIObjectBoxView()) - ->setHeaderText($title) ->setFormErrors($errors) ->setForm($form); $crumbs = $this ->buildApplicationCrumbs() - ->addTextCrumb($title); + ->addTextCrumb($title) + ->setBorder(true); - $title = pht('Edit Rule'); + $header = id(new PHUIHeaderView()) + ->setHeader($title) + ->setHeaderIcon('fa-plus-square'); + + $view = id(new PHUITwoColumnView()) + ->setHeader($header) + ->setFooter($form_box); return $this->newPage() ->setTitle($title) ->setCrumbs($crumbs) ->appendChild( array( - $form_box, + $view, )); } diff --git a/src/applications/herald/controller/HeraldTestConsoleController.php b/src/applications/herald/controller/HeraldTestConsoleController.php index 1e12825291..1dd6034bb5 100644 --- a/src/applications/herald/controller/HeraldTestConsoleController.php +++ b/src/applications/herald/controller/HeraldTestConsoleController.php @@ -98,21 +98,29 @@ final class HeraldTestConsoleController extends HeraldController { ->setValue(pht('Test Rules'))); $box = id(new PHUIObjectBoxView()) - ->setHeaderText(pht('Herald Test Console')) ->setFormErrors($errors) ->setForm($form); $crumbs = id($this->buildApplicationCrumbs()) - ->addTextCrumb(pht('Test Console')); + ->addTextCrumb(pht('Test Console')) + ->setBorder(true); $title = pht('Test Console'); + $header = id(new PHUIHeaderView()) + ->setHeader($title) + ->setHeaderIcon('fa-desktop'); + + $view = id(new PHUITwoColumnView()) + ->setHeader($header) + ->setFooter($box); + return $this->newPage() ->setTitle($title) ->setCrumbs($crumbs) ->appendChild( array( - $box, + $view, )); } diff --git a/src/applications/herald/controller/HeraldTranscriptController.php b/src/applications/herald/controller/HeraldTranscriptController.php index afb7b36558..e15c7ed52c 100644 --- a/src/applications/herald/controller/HeraldTranscriptController.php +++ b/src/applications/herald/controller/HeraldTranscriptController.php @@ -79,16 +79,25 @@ final class HeraldTranscriptController extends HeraldController { ->addTextCrumb( pht('Transcripts'), $this->getApplicationURI('/transcript/')) - ->addTextCrumb($xscript->getID()); + ->addTextCrumb($xscript->getID()) + ->setBorder(true); - $title = pht('Transcript'); + $title = pht('Transcript: %s', $xscript->getID()); + + $header = id(new PHUIHeaderView()) + ->setHeader($title) + ->setHeaderIcon('fa-file'); + + $view = id(new PHUITwoColumnView()) + ->setHeader($header) + ->setFooter($content); return $this->newPage() ->setTitle($title) ->setCrumbs($crumbs) ->appendChild( array( - $content, + $view, )); } @@ -232,7 +241,8 @@ final class HeraldTranscriptController extends HeraldController { $action_map = mgroup($action_map, 'getRuleID'); $rule_list = id(new PHUIObjectItemListView()) - ->setNoDataString(pht('No Herald rules applied to this object.')); + ->setNoDataString(pht('No Herald rules applied to this object.')) + ->setFlush(true); $rule_xscripts = $xscript->getRuleTranscripts(); $rule_xscripts = msort($rule_xscripts, 'getRuleID'); diff --git a/webroot/rsrc/css/phui/phui-form-view.css b/webroot/rsrc/css/phui/phui-form-view.css index 8973a7441b..6f88db302f 100644 --- a/webroot/rsrc/css/phui/phui-form-view.css +++ b/webroot/rsrc/css/phui/phui-form-view.css @@ -263,11 +263,10 @@ table.aphront-form-control-checkbox-layout th { } .phui-form-inset { - margin: 4px 0 8px; + margin: 12px 0; padding: 8px; background: #f7f9fd; border: 1px solid {$lightblueborder}; - border-bottom: 1px solid {$blueborder}; border-radius: 3px; } From 1507e8dc8bf647882ec38d75478030a67fcc0f24 Mon Sep 17 00:00:00 2001 From: epriestley Date: Fri, 1 Apr 2016 05:52:14 -0700 Subject: [PATCH 34/42] Change "Projects" to "Tags" for curtain extension Summary: This doesn't hit the ambiguous case in Diffusion so it seems fine to make it more consistent. Test Plan: Looked at a little task-o. Reviewers: chad Reviewed By: chad Differential Revision: https://secure.phabricator.com/D15561 --- .../engineextension/PhabricatorProjectsCurtainExtension.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/applications/project/engineextension/PhabricatorProjectsCurtainExtension.php b/src/applications/project/engineextension/PhabricatorProjectsCurtainExtension.php index cc394c2283..c69e130275 100644 --- a/src/applications/project/engineextension/PhabricatorProjectsCurtainExtension.php +++ b/src/applications/project/engineextension/PhabricatorProjectsCurtainExtension.php @@ -83,7 +83,7 @@ final class PhabricatorProjectsCurtainExtension } return $this->newPanel() - ->setHeaderText(pht('Projects')) + ->setHeaderText(pht('Tags')) ->setOrder(10000) ->appendChild($list); } From ad7239d64ccfa8ba163fa9f05a52a59e332a0b97 Mon Sep 17 00:00:00 2001 From: epriestley Date: Fri, 1 Apr 2016 06:02:53 -0700 Subject: [PATCH 35/42] Don't show continuation lines in "stacked action" comment previews Summary: Ref T10698. Currently, we show the spacer/continuation lines around previews, but these don't make sense in previews. (Other stuff also uses this code so I can't simply remove `spacer`.) Test Plan: Before: {F1199924} After: {F1199925} Reviewers: chad Reviewed By: chad Maniphest Tasks: T10698 Differential Revision: https://secure.phabricator.com/D15562 --- .../js/application/transactions/behavior-comment-actions.js | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/webroot/rsrc/js/application/transactions/behavior-comment-actions.js b/webroot/rsrc/js/application/transactions/behavior-comment-actions.js index be28e0bdad..87cb80c74a 100644 --- a/webroot/rsrc/js/application/transactions/behavior-comment-actions.js +++ b/webroot/rsrc/js/application/transactions/behavior-comment-actions.js @@ -148,10 +148,7 @@ JX.behavior('comment-actions', function(config) { } else { JX.DOM.setContent( JX.$(config.timelineID), - [ - JX.$H(response.spacer), - JX.$H(response.xactions.join(response.spacer)) - ]); + JX.$H(response.xactions.join(''))); JX.DOM.show(panel); } } From bf1042c2f6b6a3144a35cf21b186d49c4b2ddd11 Mon Sep 17 00:00:00 2001 From: epriestley Date: Fri, 1 Apr 2016 08:20:10 -0700 Subject: [PATCH 36/42] Long-chain starchy carbohydrates. --- resources/celerity/map.php | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/resources/celerity/map.php b/resources/celerity/map.php index a4917e52e6..3d5f59abe7 100644 --- a/resources/celerity/map.php +++ b/resources/celerity/map.php @@ -433,7 +433,7 @@ return array( 'rsrc/js/application/search/behavior-reorder-profile-menu-items.js' => 'e2e0a072', 'rsrc/js/application/search/behavior-reorder-queries.js' => 'e9581f08', 'rsrc/js/application/slowvote/behavior-slowvote-embed.js' => '887ad43f', - 'rsrc/js/application/transactions/behavior-comment-actions.js' => '1f2fcaf8', + 'rsrc/js/application/transactions/behavior-comment-actions.js' => '06460e71', 'rsrc/js/application/transactions/behavior-reorder-configs.js' => 'd7a74243', 'rsrc/js/application/transactions/behavior-reorder-fields.js' => 'b59e1e96', 'rsrc/js/application/transactions/behavior-show-older-transactions.js' => 'dbbf48b6', @@ -580,7 +580,7 @@ return array( 'javelin-behavior-audit-preview' => 'd835b03a', 'javelin-behavior-bulk-job-reload' => 'edf8a145', 'javelin-behavior-choose-control' => '327a00d1', - 'javelin-behavior-comment-actions' => '1f2fcaf8', + 'javelin-behavior-comment-actions' => '06460e71', 'javelin-behavior-config-reorder-fields' => 'b6993408', 'javelin-behavior-conpherence-drag-and-drop-photo' => 'cf86d16a', 'javelin-behavior-conpherence-menu' => '1d45c74d', @@ -920,6 +920,15 @@ return array( 'aphront-typeahead-control-css', 'phui-tag-view-css', ), + '06460e71' => array( + 'javelin-behavior', + 'javelin-stratcom', + 'javelin-workflow', + 'javelin-dom', + 'phuix-form-control-view', + 'phuix-icon-view', + 'javelin-behavior-phabricator-gesture', + ), '065227cc' => array( 'javelin-behavior', 'javelin-dom', @@ -1025,15 +1034,6 @@ return array( 'javelin-dom', 'javelin-reactor-dom', ), - '1f2fcaf8' => array( - 'javelin-behavior', - 'javelin-stratcom', - 'javelin-workflow', - 'javelin-dom', - 'phuix-form-control-view', - 'phuix-icon-view', - 'javelin-behavior-phabricator-gesture', - ), '21ba5861' => array( 'javelin-behavior', 'javelin-dom', From 7a6acd57faacc1a30bb67308daa3c7b5c2558675 Mon Sep 17 00:00:00 2001 From: lkassianik Date: Thu, 31 Mar 2016 17:05:12 -0700 Subject: [PATCH 37/42] Allow ordering of badges by quality Summary: Ref T9007 Test Plan: Navigate to "Advanced Search" in Badges, order by rarity, then by commonality. Rarest and most common badges should be ordered, respectively. Reviewers: #blessed_reviewers, epriestley Reviewed By: #blessed_reviewers, epriestley Subscribers: Korvin Maniphest Tasks: T9007 Differential Revision: https://secure.phabricator.com/D15555 --- .../badges/query/PhabricatorBadgesQuery.php | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/src/applications/badges/query/PhabricatorBadgesQuery.php b/src/applications/badges/query/PhabricatorBadgesQuery.php index fce8b3731f..c5d8b2dd12 100644 --- a/src/applications/badges/query/PhabricatorBadgesQuery.php +++ b/src/applications/badges/query/PhabricatorBadgesQuery.php @@ -105,4 +105,36 @@ final class PhabricatorBadgesQuery return 'PhabricatorBadgesApplication'; } + public function getBuiltinOrders() { + return array( + 'quality' => array( + 'vector' => array('quality', 'id'), + 'name' => pht('Rarity (Rarest First)'), + ), + 'shoddiness' => array( + 'vector' => array('-quality', '-id'), + 'name' => pht('Rarity (Most Common First)'), + ), + ) + parent::getBuiltinOrders(); + } + + public function getOrderableColumns() { + return array( + 'quality' => array( + 'table' => $this->getPrimaryTableAlias(), + 'column' => 'quality', + 'reverse' => true, + 'type' => 'int', + ), + ) + parent::getOrderableColumns(); + } + + protected function getPagingValueMap($cursor, array $keys) { + $badge = $this->loadCursorObject($cursor); + return array( + 'quality' => $badge->getQuality(), + 'id' => $badge->getID(), + ); + } + } From ff4a63a9540c4efc04a208e8298f103b8b4dec15 Mon Sep 17 00:00:00 2001 From: Chad Little Date: Fri, 1 Apr 2016 12:25:39 -0700 Subject: [PATCH 38/42] Moderize Pholio UI Summary: Cleans up Pholio, moves to two column layout, fix some transaction inconsistencies. This moves "Image" to the MainColumn, which feels fine, but I think we'll likely want some sort of "fullscreen" option for Pholio V2 like we have on workboards perhaps. Test Plan: New Mock, Edit Mock, View Mock. {F1200450} Reviewers: epriestley Reviewed By: epriestley Subscribers: Korvin Differential Revision: https://secure.phabricator.com/D15564 --- .../controller/PholioMockEditController.php | 24 ++-- .../controller/PholioMockViewController.php | 125 ++++++++++-------- .../pholio/storage/PholioMock.php | 6 +- .../pholio/storage/PholioTransaction.php | 48 +++++-- .../pholio/view/PholioMockThumbGridView.php | 1 + 5 files changed, 120 insertions(+), 84 deletions(-) diff --git a/src/applications/pholio/controller/PholioMockEditController.php b/src/applications/pholio/controller/PholioMockEditController.php index 60c4202444..f3dedc9a33 100644 --- a/src/applications/pholio/controller/PholioMockEditController.php +++ b/src/applications/pholio/controller/PholioMockEditController.php @@ -22,7 +22,8 @@ final class PholioMockEditController extends PholioController { return new Aphront404Response(); } - $title = pht('Edit Mock'); + $title = pht('Edit Mock: %s', $mock->getName()); + $header_icon = 'fa-pencil'; $is_new = false; $mock_images = $mock->getImages(); @@ -32,6 +33,7 @@ final class PholioMockEditController extends PholioController { $mock = PholioMock::initializeNewMock($viewer); $title = pht('Create Mock'); + $header_icon = 'fa-plus-square'; $is_new = true; $files = array(); @@ -350,8 +352,9 @@ final class PholioMockEditController extends PholioController { ->appendChild($submit); $form_box = id(new PHUIObjectBoxView()) - ->setHeaderText($title) + ->setHeaderText(pht('Mock')) ->setFormErrors($errors) + ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) ->setForm($form); $crumbs = $this->buildApplicationCrumbs(); @@ -359,21 +362,22 @@ final class PholioMockEditController extends PholioController { $crumbs->addTextCrumb($mock->getMonogram(), '/'.$mock->getMonogram()); } $crumbs->addTextCrumb($title); + $crumbs->setBorder(true); - $content = array( - $crumbs, - $form_box, - ); + $header = id(new PHUIHeaderView()) + ->setHeader($title) + ->setHeaderIcon($header_icon); + + $view = id(new PHUITwoColumnView()) + ->setHeader($header) + ->setFooter($form_box); return $this->newPage() ->setTitle($title) ->setCrumbs($crumbs) ->addQuicksandConfig( array('mockEditConfig' => true)) - ->appendChild( - array( - $form_box, - )); + ->appendChild($view); } } diff --git a/src/applications/pholio/controller/PholioMockViewController.php b/src/applications/pholio/controller/PholioMockViewController.php index 78c1d4bfe9..565d2d6cb4 100644 --- a/src/applications/pholio/controller/PholioMockViewController.php +++ b/src/applications/pholio/controller/PholioMockViewController.php @@ -57,7 +57,8 @@ final class PholioMockViewController extends PholioController { ->setHeader($title) ->setUser($viewer) ->setStatus($header_icon, $header_color, $header_name) - ->setPolicyObject($mock); + ->setPolicyObject($mock) + ->setHeaderIcon('fa-camera-retro'); $timeline = $this->buildTransactionTimeline( $mock, @@ -65,8 +66,8 @@ final class PholioMockViewController extends PholioController { $engine); $timeline->setMock($mock); - $actions = $this->buildActionView($mock); - $properties = $this->buildPropertyView($mock, $engine, $actions); + $curtain = $this->buildCurtainView($mock); + $details = $this->buildDescriptionView($mock, $engine); require_celerity_resource('pholio-css'); require_celerity_resource('pholio-inline-comments-css'); @@ -80,51 +81,50 @@ final class PholioMockViewController extends PholioController { ->setImageID($image_id); $output = id(new PHUIObjectBoxView()) - ->setHeaderText(pht('Image')) + ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) ->appendChild($mock_view); $add_comment = $this->buildAddCommentView($mock, $comment_form_id); $crumbs = $this->buildApplicationCrumbs(); $crumbs->addTextCrumb('M'.$mock->getID(), '/M'.$mock->getID()); - - $object_box = id(new PHUIObjectBoxView()) - ->setHeader($header) - ->addPropertyList($properties); + $crumbs->setBorder(true); $thumb_grid = id(new PholioMockThumbGridView()) ->setUser($viewer) ->setMock($mock); + $view = id(new PHUITwoColumnView()) + ->setHeader($header) + ->setCurtain($curtain) + ->setMainColumn(array( + $output, + $thumb_grid, + $details, + $timeline, + $add_comment, + )); + return $this->newPage() ->setTitle('M'.$mock->getID().' '.$title) ->setCrumbs($crumbs) ->setPageObjectPHIDs(array($mock->getPHID())) ->addQuicksandConfig( array('mockViewConfig' => $mock_view->getBehaviorConfig())) - ->appendChild( - array( - $object_box, - $output, - $thumb_grid, - $timeline, - $add_comment, - )); + ->appendChild($view); } - private function buildActionView(PholioMock $mock) { + private function buildCurtainView(PholioMock $mock) { $viewer = $this->getViewer(); - $actions = id(new PhabricatorActionListView()) - ->setUser($viewer) - ->setObject($mock); + $curtain = $this->newCurtainView($mock); $can_edit = PhabricatorPolicyFilter::hasCapability( $viewer, $mock, PhabricatorPolicyCapability::CAN_EDIT); - $actions->addAction( + $curtain->addAction( id(new PhabricatorActionView()) ->setIcon('fa-pencil') ->setName(pht('Edit Mock')) @@ -133,7 +133,7 @@ final class PholioMockViewController extends PholioController { ->setWorkflow(!$can_edit)); if ($mock->isClosed()) { - $actions->addAction( + $curtain->addAction( id(new PhabricatorActionView()) ->setIcon('fa-check') ->setName(pht('Open Mock')) @@ -141,7 +141,7 @@ final class PholioMockViewController extends PholioController { ->setDisabled(!$can_edit) ->setWorkflow(true)); } else { - $actions->addAction( + $curtain->addAction( id(new PhabricatorActionView()) ->setIcon('fa-ban') ->setName(pht('Close Mock')) @@ -150,7 +150,7 @@ final class PholioMockViewController extends PholioController { ->setWorkflow(true)); } - $actions->addAction( + $curtain->addAction( id(new PhabricatorActionView()) ->setIcon('fa-anchor') ->setName(pht('Edit Maniphest Tasks')) @@ -158,45 +158,56 @@ final class PholioMockViewController extends PholioController { ->setDisabled(!$viewer->isLoggedIn()) ->setWorkflow(true)); - return $actions; - } - - private function buildPropertyView( - PholioMock $mock, - PhabricatorMarkupEngine $engine, - PhabricatorActionListView $actions) { - - $viewer = $this->getViewer(); - - $properties = id(new PHUIPropertyListView()) - ->setUser($viewer) - ->setObject($mock) - ->setActionList($actions); - - $properties->addProperty( - pht('Author'), - $viewer->renderHandle($mock->getAuthorPHID())); - - $properties->addProperty( - pht('Created'), - phabricator_datetime($mock->getDateCreated(), $viewer)); - if ($this->getManiphestTaskPHIDs()) { - $properties->addProperty( - pht('Maniphest Tasks'), - $viewer->renderHandleList($this->getManiphestTaskPHIDs())); + $curtain->newPanel() + ->setHeaderText(pht('Maniphest Tasks')) + ->appendChild( + $viewer->renderHandleList($this->getManiphestTaskPHIDs())); } - $properties->invokeWillRenderEvent(); + $curtain->newPanel() + ->setHeaderText(pht('Authored By')) + ->appendChild($this->buildAuthorPanel($mock)); - $properties->addSectionHeader( - pht('Description'), - PHUIPropertyListView::ICON_SUMMARY); + return $curtain; + } - $properties->addImageContent( - $engine->getOutput($mock, PholioMock::MARKUP_FIELD_DESCRIPTION)); + private function buildDescriptionView(PholioMock $mock) { - return $properties; + $viewer = $this->getViewer(); + $properties = id(new PHUIPropertyListView()) + ->setUser($viewer); + $description = $mock->getDescription(); + + if (strlen($description)) { + $properties->addImageContent($description); + return id(new PHUIObjectBoxView()) + ->setHeaderText(pht('Mock Description')) + ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) + ->appendChild($properties); + } + + return null; + } + + private function buildAuthorPanel(PholioMock $mock) { + $viewer = $this->getViewer(); + $author_phid = $mock->getAuthorPHID(); + $handles = $viewer->loadHandles(array($author_phid)); + + $author_uri = $handles[$author_phid]->getImageURI(); + $author_href = $handles[$author_phid]->getURI(); + $author = $viewer->renderHandle($author_phid)->render(); + + $content = phutil_tag('strong', array(), $author); + $date = phabricator_date($mock->getDateCreated(), $viewer); + $content = pht('%s, %s', $content, $date); + $authored_by = id(new PHUIHeadThingView()) + ->setImage($author_uri) + ->setImageHref($author_href) + ->setContent($content); + + return $authored_by; } private function buildAddCommentView(PholioMock $mock, $comment_form_id) { diff --git a/src/applications/pholio/storage/PholioMock.php b/src/applications/pholio/storage/PholioMock.php index 49cf2ace5d..00e8efd981 100644 --- a/src/applications/pholio/storage/PholioMock.php +++ b/src/applications/pholio/storage/PholioMock.php @@ -227,12 +227,10 @@ final class PholioMock extends PholioDAO public function getMarkupText($field) { if ($this->getDescription()) { - $description = $this->getDescription(); - } else { - $description = pht('No Description Given'); + return $this->getDescription(); } - return $description; + return null; } public function didMarkupText($field, $output, PhutilMarkupEngine $engine) { diff --git a/src/applications/pholio/storage/PholioTransaction.php b/src/applications/pholio/storage/PholioTransaction.php index 17b0730dcb..d98c6b451b 100644 --- a/src/applications/pholio/storage/PholioTransaction.php +++ b/src/applications/pholio/storage/PholioTransaction.php @@ -81,12 +81,21 @@ final class PholioTransaction extends PhabricatorApplicationTransaction { } public function getIcon() { + + $new = $this->getNewValue(); + $old = $this->getOldValue(); + switch ($this->getTransactionType()) { case self::TYPE_INLINE: return 'fa-comment'; case self::TYPE_NAME: case self::TYPE_DESCRIPTION: case self::TYPE_STATUS: + if ($new == PholioMock::STATUS_CLOSED) { + return 'fa-ban'; + } else { + return 'fa-check'; + } case self::TYPE_IMAGE_NAME: case self::TYPE_IMAGE_DESCRIPTION: case self::TYPE_IMAGE_SEQUENCE: @@ -153,9 +162,15 @@ final class PholioTransaction extends PhabricatorApplicationTransaction { $this->renderHandleLink($author_phid)); break; case self::TYPE_STATUS: - return pht( - "%s updated the mock's status.", - $this->renderHandleLink($author_phid)); + if ($new == PholioMock::STATUS_CLOSED) { + return pht( + '%s closed this mock.', + $this->renderHandleLink($author_phid)); + } else { + return pht( + '%s opened this mock.', + $this->renderHandleLink($author_phid)); + } break; case self::TYPE_INLINE: $count = 1; @@ -260,10 +275,17 @@ final class PholioTransaction extends PhabricatorApplicationTransaction { $this->renderHandleLink($object_phid)); break; case self::TYPE_STATUS: - return pht( - '%s updated the status for %s.', - $this->renderHandleLink($author_phid), - $this->renderHandleLink($object_phid)); + if ($new == PholioMock::STATUS_CLOSED) { + return pht( + '%s closed a mock %s.', + $this->renderHandleLink($author_phid), + $this->renderHandleLink($object_phid)); + } else { + return pht( + '%s opened a mock %s.', + $this->renderHandleLink($author_phid), + $this->renderHandleLink($object_phid)); + } break; case self::TYPE_INLINE: return pht( @@ -347,16 +369,16 @@ final class PholioTransaction extends PhabricatorApplicationTransaction { $new = $this->getNewValue(); switch ($this->getTransactionType()) { + case self::TYPE_STATUS: + if ($new == PholioMock::STATUS_CLOSED) { + return PhabricatorTransactions::COLOR_INDIGO; + } else { + return PhabricatorTransactions::COLOR_GREEN; + } case self::TYPE_NAME: if ($old === null) { return PhabricatorTransactions::COLOR_GREEN; } - case self::TYPE_DESCRIPTION: - case self::TYPE_STATUS: - case self::TYPE_IMAGE_NAME: - case self::TYPE_IMAGE_DESCRIPTION: - case self::TYPE_IMAGE_SEQUENCE: - return PhabricatorTransactions::COLOR_BLUE; case self::TYPE_IMAGE_REPLACE: return PhabricatorTransactions::COLOR_YELLOW; case self::TYPE_IMAGE_FILE: diff --git a/src/applications/pholio/view/PholioMockThumbGridView.php b/src/applications/pholio/view/PholioMockThumbGridView.php index 6467106c14..457d700f1f 100644 --- a/src/applications/pholio/view/PholioMockThumbGridView.php +++ b/src/applications/pholio/view/PholioMockThumbGridView.php @@ -107,6 +107,7 @@ final class PholioMockThumbGridView extends AphrontView { return id(new PHUIObjectBoxView()) ->setHeaderText(pht('Mock History')) + ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) ->appendChild($grid); } From 61301ead90e4189982cbfedce8b9b94083f02df7 Mon Sep 17 00:00:00 2001 From: epriestley Date: Fri, 1 Apr 2016 12:52:31 -0700 Subject: [PATCH 39/42] Fix javascript interaction with right-hand-side images in two-up diff views in Differential Summary: Fixes T10704. This is just bad copy-paste -- "O" for "old" should be "N" for "new". Test Plan: - Followed steps on T10704. - Applied patch. - Marked inline done, replied, etc. No more JS errors. Reviewers: chad Reviewed By: chad Maniphest Tasks: T10704 Differential Revision: https://secure.phabricator.com/D15566 --- .../differential/render/DifferentialChangesetTwoUpRenderer.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/applications/differential/render/DifferentialChangesetTwoUpRenderer.php b/src/applications/differential/render/DifferentialChangesetTwoUpRenderer.php index 16752b9402..0932f63454 100644 --- a/src/applications/differential/render/DifferentialChangesetTwoUpRenderer.php +++ b/src/applications/differential/render/DifferentialChangesetTwoUpRenderer.php @@ -376,7 +376,7 @@ final class DifferentialChangesetTwoUpRenderer if (!$new) { $th_new = phutil_tag('th', array()); } else { - $th_new = phutil_tag('th', array('id' => "C{$id}OL1"), 1); + $th_new = phutil_tag('th', array('id' => "C{$id}NL1"), 1); } $output = hsprintf( From 1f107b8fe046eeb62a9f65a5d3d1889cb692c388 Mon Sep 17 00:00:00 2001 From: Chad Little Date: Fri, 1 Apr 2016 13:40:29 -0700 Subject: [PATCH 40/42] Update Calendar Edit for new UI Summary: Updates Calendar Edit UI with new header layout Test Plan: New Event, Public, Recurring, Edit Event Reviewers: epriestley Reviewed By: epriestley Subscribers: Korvin Differential Revision: https://secure.phabricator.com/D15567 --- ...PhabricatorCalendarEventEditController.php | 41 +++++++++++-------- 1 file changed, 24 insertions(+), 17 deletions(-) diff --git a/src/applications/calendar/controller/PhabricatorCalendarEventEditController.php b/src/applications/calendar/controller/PhabricatorCalendarEventEditController.php index 389d7b7358..10ed2b84e0 100644 --- a/src/applications/calendar/controller/PhabricatorCalendarEventEditController.php +++ b/src/applications/calendar/controller/PhabricatorCalendarEventEditController.php @@ -69,7 +69,8 @@ final class PhabricatorCalendarEventEditController $recurrence_end_date_value->setOptional(true); $submit_label = pht('Create'); - $page_title = pht('Create Event'); + $title = pht('Create Event'); + $header_icon = 'fa-plus-square'; $redirect = 'created'; $subscribers = array(); $invitees = array($user_phid); @@ -121,7 +122,8 @@ final class PhabricatorCalendarEventEditController ->setOptional(true); $submit_label = pht('Update'); - $page_title = pht('Update Event'); + $title = pht('Edit Event: %s', $event->getName()); + $header_icon = 'fa-pencil'; $subscribers = PhabricatorSubscribersQuery::loadSubscribersForPHID( $event->getPHID()); @@ -540,7 +542,7 @@ final class PhabricatorCalendarEventEditController if ($request->isAjax()) { return $this->newDialog() - ->setTitle($page_title) + ->setTitle($title) ->setWidth(AphrontDialogView::WIDTH_FULL) ->appendForm($form) ->addCancelButton($cancel_uri) @@ -554,30 +556,35 @@ final class PhabricatorCalendarEventEditController $form->appendChild($submit); $form_box = id(new PHUIObjectBoxView()) - ->setHeaderText($page_title) + ->setHeaderText(pht('Event')) + ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) + ->setValidationException($validation_exception) ->setForm($form); $crumbs = $this->buildApplicationCrumbs(); if (!$this->isCreate()) { $crumbs->addTextCrumb('E'.$event->getId(), '/E'.$event->getId()); + $crumb_title = pht('Edit Event'); + } else { + $crumb_title = pht('Create Event'); } - $crumbs->addTextCrumb($page_title); + $crumbs->addTextCrumb($crumb_title); + $crumbs->setBorder(true); - $object_box = id(new PHUIObjectBoxView()) - ->setHeaderText($page_title) - ->setValidationException($validation_exception) - ->appendChild($form); + $header = id(new PHUIHeaderView()) + ->setHeader($title) + ->setHeaderIcon($header_icon); - return $this->buildApplicationPage( - array( - $crumbs, - $object_box, - ), - array( - 'title' => $page_title, - )); + $view = id(new PHUITwoColumnView()) + ->setHeader($header) + ->setFooter($form_box); + + return $this->newPage() + ->setTitle($title) + ->setCrumbs($crumbs) + ->appendChild($view); } From 399b23d6307736ec66585da19af2dcd5ac066c7f Mon Sep 17 00:00:00 2001 From: Chad Little Date: Fri, 1 Apr 2016 21:08:51 +0000 Subject: [PATCH 41/42] Update Macro Edit for new UI Summary: Updates Edit/Create page for Macro to new headers Test Plan: Create Macro, Edit Macro Reviewers: epriestley Reviewed By: epriestley Subscribers: Korvin Differential Revision: https://secure.phabricator.com/D15568 --- .../PhabricatorMacroEditController.php | 30 +++++++++++++------ 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/src/applications/macro/controller/PhabricatorMacroEditController.php b/src/applications/macro/controller/PhabricatorMacroEditController.php index 9e988ef637..4e6fa314b0 100644 --- a/src/applications/macro/controller/PhabricatorMacroEditController.php +++ b/src/applications/macro/controller/PhabricatorMacroEditController.php @@ -233,16 +233,19 @@ final class PhabricatorMacroEditController extends PhabricatorMacroController { $crumbs = $this->buildApplicationCrumbs(); if ($macro->getID()) { - $title = pht('Edit Image Macro'); + $title = pht('Edit Macro: %s', $macro->getName()); $crumb = pht('Edit Macro'); + $header_icon = 'fa-pencil'; - $crumbs->addTextCrumb(pht('Macro "%s"', $macro->getName()), $view_uri); + $crumbs->addTextCrumb(pht('Macro: %s', $macro->getName()), $view_uri); } else { $title = pht('Create Image Macro'); $crumb = pht('Create Macro'); + $header_icon = 'fa-plus-square'; } $crumbs->addTextCrumb($crumb, $request->getRequestURI()); + $crumbs->setBorder(true); $upload = null; if ($macro->getID()) { @@ -267,23 +270,32 @@ final class PhabricatorMacroEditController extends PhabricatorMacroController { $upload = id(new PHUIObjectBoxView()) ->setHeaderText(pht('Upload New File')) + ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) ->setForm($upload_form); } $form_box = id(new PHUIObjectBoxView()) - ->setHeaderText($title) + ->setHeaderText(pht('Macro')) ->setFormErrors($errors) + ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) ->setForm($form); - return $this->buildApplicationPage( - array( - $crumbs, + $header = id(new PHUIHeaderView()) + ->setHeader($title) + ->setHeaderIcon($header_icon); + + $view = id(new PHUITwoColumnView()) + ->setHeader($header) + ->setFooter(array( $form_box, $upload, - ), - array( - 'title' => $title, )); + + return $this->newPage() + ->setTitle($title) + ->setCrumbs($crumbs) + ->appendChild($view); + } } From 59efb7bdf327cbdb953c8b4b0d7cfe78e6ef6f3b Mon Sep 17 00:00:00 2001 From: Chad Little Date: Fri, 1 Apr 2016 14:07:41 -0700 Subject: [PATCH 42/42] Update Meta for new UI Summary: Runs through Meta, cleaned up policies and editing email addresses to new UI Test Plan: Set a new Email address for Maniphest, edit policies. Reviewers: epriestley Reviewed By: epriestley Subscribers: Korvin Differential Revision: https://secure.phabricator.com/D15569 --- ...ricatorApplicationDetailViewController.php | 3 +-- .../PhabricatorApplicationEditController.php | 21 ++++++++++++------- ...atorApplicationEmailCommandsController.php | 12 ++++------- .../PhabricatorApplicationPanelController.php | 11 +++++++--- ...habricatorMetaMTAApplicationEmailPanel.php | 21 +++++++++++-------- 5 files changed, 38 insertions(+), 30 deletions(-) diff --git a/src/applications/meta/controller/PhabricatorApplicationDetailViewController.php b/src/applications/meta/controller/PhabricatorApplicationDetailViewController.php index 443a7e37d3..f86f9eb4d1 100644 --- a/src/applications/meta/controller/PhabricatorApplicationDetailViewController.php +++ b/src/applications/meta/controller/PhabricatorApplicationDetailViewController.php @@ -123,8 +123,7 @@ final class PhabricatorApplicationDetailViewController PhabricatorApplication $application) { $viewer = $this->getViewer(); - $properties = id(new PHUIPropertyListView()) - ->setStacked(true); + $properties = id(new PHUIPropertyListView()); $header = id(new PHUIHeaderView()) ->setHeader(pht('POLICIES')) diff --git a/src/applications/meta/controller/PhabricatorApplicationEditController.php b/src/applications/meta/controller/PhabricatorApplicationEditController.php index d9d7b3c15c..ed51405db9 100644 --- a/src/applications/meta/controller/PhabricatorApplicationEditController.php +++ b/src/applications/meta/controller/PhabricatorApplicationEditController.php @@ -171,22 +171,27 @@ final class PhabricatorApplicationEditController $crumbs = $this->buildApplicationCrumbs(); $crumbs->addTextCrumb($application->getName(), $view_uri); $crumbs->addTextCrumb(pht('Edit Policies')); + $crumbs->setBorder(true); $header = id(new PHUIHeaderView()) - ->setHeader(pht('Edit Policies: %s', $application->getName())); + ->setHeader(pht('Edit Policies: %s', $application->getName())) + ->setHeaderIcon('fa-pencil'); $object_box = id(new PHUIObjectBoxView()) - ->setHeader($header) + ->setHeaderText(pht('Policies')) + ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) ->setForm($form); - return $this->buildApplicationPage( - array( - $crumbs, + $view = id(new PHUITwoColumnView()) + ->setHeader($header) + ->setFooter(array( $object_box, - ), - array( - 'title' => $title, )); + + return $this->newPage() + ->setTitle($title) + ->setCrumbs($crumbs) + ->appendChild($view); } } diff --git a/src/applications/meta/controller/PhabricatorApplicationEmailCommandsController.php b/src/applications/meta/controller/PhabricatorApplicationEmailCommandsController.php index 08f8e450b5..2979e92229 100644 --- a/src/applications/meta/controller/PhabricatorApplicationEmailCommandsController.php +++ b/src/applications/meta/controller/PhabricatorApplicationEmailCommandsController.php @@ -137,14 +137,10 @@ final class PhabricatorApplicationEmailCommandsController ->appendChild($info_view) ->appendChild($content_box); - return $this->buildApplicationPage( - array( - $crumbs, - $document, - ), - array( - 'title' => $title, - )); + return $this->newPage() + ->setTitle($title) + ->setCrumbs($crumbs) + ->appendChild($document); } diff --git a/src/applications/meta/controller/PhabricatorApplicationPanelController.php b/src/applications/meta/controller/PhabricatorApplicationPanelController.php index 48355d131f..4fab71c501 100644 --- a/src/applications/meta/controller/PhabricatorApplicationPanelController.php +++ b/src/applications/meta/controller/PhabricatorApplicationPanelController.php @@ -59,9 +59,14 @@ final class PhabricatorApplicationPanelController public function buildPanelPage( PhabricatorApplicationConfigurationPanel $panel, - $content, - array $options) { - return $this->buildApplicationPage($content, $options); + $title, + $crumbs, + $content) { + + return $this->newPage() + ->setTitle($title) + ->setCrumbs($crumbs) + ->appendChild($content); } } diff --git a/src/applications/metamta/applicationpanel/PhabricatorMetaMTAApplicationEmailPanel.php b/src/applications/metamta/applicationpanel/PhabricatorMetaMTAApplicationEmailPanel.php index 1899ac1be1..a2d32e3360 100644 --- a/src/applications/metamta/applicationpanel/PhabricatorMetaMTAApplicationEmailPanel.php +++ b/src/applications/metamta/applicationpanel/PhabricatorMetaMTAApplicationEmailPanel.php @@ -37,6 +37,7 @@ final class PhabricatorMetaMTAApplicationEmailPanel $box = id(new PHUIObjectBoxView()) ->setHeader($header) + ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) ->setTable($table); return $box; @@ -81,10 +82,12 @@ final class PhabricatorMetaMTAApplicationEmailPanel $crumbs = $controller->buildPanelCrumbs($this); $crumbs->addTextCrumb(pht('Edit Application Emails')); + $crumbs->setBorder(true); $header = id(new PHUIHeaderView()) ->setHeader(pht('Edit Application Emails: %s', $application->getName())) - ->setSubheader($application->getAppEmailBlurb()); + ->setSubheader($application->getAppEmailBlurb()) + ->setHeaderIcon('fa-pencil'); $icon = id(new PHUIIconView()) ->setIcon('fa-plus'); @@ -97,20 +100,20 @@ final class PhabricatorMetaMTAApplicationEmailPanel $header->addActionLink($button); $object_box = id(new PHUIObjectBoxView()) - ->setHeader($header) + ->setHeaderText(pht('Emails')) + ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) ->setTable($table); $title = $application->getName(); + $view = id(new PHUITwoColumnView()) + ->setHeader($header) + ->setFooter($object_box); return $controller->buildPanelPage( $this, - array( - $crumbs, - $object_box, - ), - array( - 'title' => $title, - )); + $title, + $crumbs, + $view); } private function returnNewAddressResponse(