From eb0bb1736891e0d8bfc5bcb5ea16d60b016e58d7 Mon Sep 17 00:00:00 2001 From: Aviv Eyal Date: Fri, 11 Aug 2023 11:27:50 -0700 Subject: [PATCH 01/93] Replace dedicated Commit Field with an existing one Summary: fix T15600 Test Plan: arc diff against this Reviewers: Sten, O1 Blessed Committers! Reviewed By: Sten Subscribers: speck, tobiaswiese, valerio.bozzolan, Matthew, Cigaryno Maniphest Tasks: T15600 Differential Revision: https://we.phorge.it/D25385 --- src/__phutil_library_map__.php | 2 -- .../field/DifferentialTestCommitMessageField.php | 10 ---------- .../DifferentialCommitMessageFieldTestCase.php | 2 +- 3 files changed, 1 insertion(+), 13 deletions(-) delete mode 100644 src/applications/differential/field/DifferentialTestCommitMessageField.php diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php index 83737eea52..213b6cf6b1 100644 --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -714,7 +714,6 @@ phutil_register_library_map(array( 'DifferentialTabReplacementTestCase' => 'applications/differential/parser/__tests__/DifferentialTabReplacementTestCase.php', 'DifferentialTagsCommitMessageField' => 'applications/differential/field/DifferentialTagsCommitMessageField.php', 'DifferentialTasksCommitMessageField' => 'applications/differential/field/DifferentialTasksCommitMessageField.php', - 'DifferentialTestCommitMessageField' => 'applications/differential/field/DifferentialTestCommitMessageField.php', 'DifferentialTestPlanCommitMessageField' => 'applications/differential/field/DifferentialTestPlanCommitMessageField.php', 'DifferentialTestPlanField' => 'applications/differential/customfield/DifferentialTestPlanField.php', 'DifferentialTitleCommitMessageField' => 'applications/differential/field/DifferentialTitleCommitMessageField.php', @@ -6761,7 +6760,6 @@ phutil_register_library_map(array( 'DifferentialTabReplacementTestCase' => 'PhabricatorTestCase', 'DifferentialTagsCommitMessageField' => 'DifferentialCommitMessageField', 'DifferentialTasksCommitMessageField' => 'DifferentialCommitMessageField', - 'DifferentialTestCommitMessageField' => 'DifferentialCommitMessageField', 'DifferentialTestPlanCommitMessageField' => 'DifferentialCommitMessageField', 'DifferentialTestPlanField' => 'DifferentialCoreCustomField', 'DifferentialTitleCommitMessageField' => 'DifferentialCommitMessageField', diff --git a/src/applications/differential/field/DifferentialTestCommitMessageField.php b/src/applications/differential/field/DifferentialTestCommitMessageField.php deleted file mode 100644 index 9d398bc4fd..0000000000 --- a/src/applications/differential/field/DifferentialTestCommitMessageField.php +++ /dev/null @@ -1,10 +0,0 @@ -assertEqual('foo', $test_object->renderFieldValue('foo'), 'Normal strings should be rendered unaltered'); From 10ee019785d5331150c3d83bd3549fc8c9e42fb0 Mon Sep 17 00:00:00 2001 From: Andre Klapper Date: Fri, 11 Aug 2023 20:56:23 +0200 Subject: [PATCH 02/93] Fix PHP 8.1 "strlen(null)" exception setting Passphrase Credential Summary: `strlen()` was used in Phabricator to check if a generic value is a non-empty string. This behavior is deprecated since PHP 8.1. Phorge adopts `phutil_nonempty_string()` as a replacement. Note: this may highlight other absurd input values that might be worth correcting instead of just ignoring. If phutil_nonempty_string() throws an exception in your instance, report it to Phorge to evaluate and fix that specific corner case. ``` EXCEPTION: (RuntimeException) strlen(): Passing null to parameter #1 ($string) of type string is deprecated at [/src/error/PhutilErrorHandler.php:261] arcanist(head=master, ref.master=788098096e11), phorge(head=master, ref.master=840a7fab2bc8) #0 <#2> PhutilErrorHandler::handleError(integer, string, string, integer) called at [/src/applications/passphrase/view/PassphraseCredentialControl.php:53] ``` Closes T15580 Test Plan: Set URI for a Diffusion Repository, select URI and select "Set Credential". Page "Edit Repository URI" at `/diffusion/123/uri/edit/456/` renders as expected in web browser. Reviewers: O1 Blessed Committers, Matthew Reviewed By: O1 Blessed Committers, Matthew Subscribers: avivey, speck, tobiaswiese, valerio.bozzolan, Matthew, Cigaryno Maniphest Tasks: T15580 Differential Revision: https://we.phorge.it/D25370 --- .../passphrase/view/PassphraseCredentialControl.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/applications/passphrase/view/PassphraseCredentialControl.php b/src/applications/passphrase/view/PassphraseCredentialControl.php index 8ba1ef9bc8..98294832f7 100644 --- a/src/applications/passphrase/view/PassphraseCredentialControl.php +++ b/src/applications/passphrase/view/PassphraseCredentialControl.php @@ -50,7 +50,8 @@ final class PassphraseCredentialControl extends AphrontFormControl { // credential. Populate it into the menu to allow them to save the form // without making any changes. $current_phid = $this->getValue(); - if (strlen($current_phid) && empty($options_map[$current_phid])) { + if (phutil_nonempty_string($current_phid) && + empty($options_map[$current_phid])) { $viewer = $this->getViewer(); $current_name = null; From 085769ceb687e04cfca983cbb2dee59a889d489b Mon Sep 17 00:00:00 2001 From: Andre Klapper Date: Fri, 11 Aug 2023 20:57:34 +0200 Subject: [PATCH 03/93] Fix PHP 8.1 "strlen(null)" exceptions trying to authenticate via custom OAuth provider Summary: `strlen()` was used in Phabricator to check if a generic value is a non-empty string. This behavior is deprecated since PHP 8.1. Phorge adopts `phutil_nonempty_string()` as a replacement. Note: this may highlight other absurd input values that might be worth correcting instead of just ignoring. If phutil_nonempty_string() throws an exception in your instance, report it to Phorge to evaluate and fix that specific corner case. This change also replaces two other `strlen()` calls, only based on //reading// the code but not based on triggering exceptions. ``` EXCEPTION: (RuntimeException) strlen(): Passing null to parameter #1 ($string) of type string is deprecated at [/src/error/PhutilErrorHandler.php:261] arcanist(), ava(), phorge(), wmf-ext-misc() #0 <#2> PhutilErrorHandler::handleError(integer, string, string, integer) called at [/applications/auth/adapter/PhutilOAuth1AuthAdapter.php:121] ``` ``` EXCEPTION: (RuntimeException) strlen(): Passing null to parameter #1 ($string) of type string is deprecated at [/src/error/PhutilErrorHandler.php:261] arcanist(), ava(), phorge(), wmf-ext-misc() #0 <#2> PhutilErrorHandler::handleError(integer, string, string, integer) called at [/applications/auth/adapter/PhutilOAuth1AuthAdapter.php:125] ``` Closes T15588 Test Plan: Go to `/auth/login/mediawiki:whatever/` and at least see no `strlen()` errors anymore (while further issues remain). See T15588 for details. Reviewers: O1 Blessed Committers, Matthew Reviewed By: O1 Blessed Committers, Matthew Subscribers: speck, tobiaswiese, valerio.bozzolan, Matthew, Cigaryno Maniphest Tasks: T15588 Differential Revision: https://we.phorge.it/D25373 --- src/applications/auth/adapter/PhutilOAuth1AuthAdapter.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/applications/auth/adapter/PhutilOAuth1AuthAdapter.php b/src/applications/auth/adapter/PhutilOAuth1AuthAdapter.php index 08cc65a235..389763da7d 100644 --- a/src/applications/auth/adapter/PhutilOAuth1AuthAdapter.php +++ b/src/applications/auth/adapter/PhutilOAuth1AuthAdapter.php @@ -104,7 +104,7 @@ abstract class PhutilOAuth1AuthAdapter extends PhutilAuthAdapter { ->setSignatureMethod($this->getSignatureMethod()); $consumer_key = $this->getConsumerKey(); - if (strlen($consumer_key)) { + if (phutil_nonempty_string($consumer_key)) { $future->setConsumerKey($consumer_key); } else { throw new Exception( @@ -118,11 +118,11 @@ abstract class PhutilOAuth1AuthAdapter extends PhutilAuthAdapter { $future->setConsumerSecret($consumer_secret); } - if (strlen($this->getToken())) { + if (phutil_nonempty_string($this->getToken())) { $future->setToken($this->getToken()); } - if (strlen($this->getTokenSecret())) { + if (phutil_nonempty_string($this->getTokenSecret())) { $future->setTokenSecret($this->getTokenSecret()); } @@ -137,7 +137,7 @@ abstract class PhutilOAuth1AuthAdapter extends PhutilAuthAdapter { $request_token_uri = $this->getRequestTokenURI(); $future = $this->newOAuth1Future($request_token_uri); - if (strlen($this->getCallbackURI())) { + if (phutil_nonempty_string($this->getCallbackURI())) { $future->setCallbackURI($this->getCallbackURI()); } From c61c6a1ec3c1bbfa6c7254ce824bca8a860d4417 Mon Sep 17 00:00:00 2001 From: Andre Klapper Date: Fri, 11 Aug 2023 21:00:25 +0200 Subject: [PATCH 04/93] Fix PHP 8.1 "strlen(null)" exception adding a Harbormaster Build Plan Summary: `strlen()` was used in Phabricator to check if a generic value is a non-empty string. This behavior is deprecated since PHP 8.1. Phorge adopts `phutil_nonempty_string()` as a replacement. Note: this may highlight other absurd input values that might be worth correcting instead of just ignoring. If phutil_nonempty_string() throws an exception in your instance, report it to Phorge to evaluate and fix that specific corner case. ``` EXCEPTION: (RuntimeException) strlen(): Passing null to parameter #1 ($string) of type string is deprecated at [/src/error/PhutilErrorHandler.php:261] arcanist(head=customOAuthUrlencodeNull, ref.master=788098096e11, ref.customOAuthUrlencodeNull=4f0f2043b7e9), phorge(head=master, ref.master=226f3150933d) #0 <#2> PhutilErrorHandler::handleError(integer, string, string, integer) called at [/src/applications/harbormaster/editor/HarbormasterBuildPlanEditEngine.php:106] ``` Closes T15591 Test Plan: Visit `/harbormaster/plan/edit/form/default/`. "Create Build Plan" page renders as expected. Reviewers: O1 Blessed Committers, Matthew Reviewed By: O1 Blessed Committers, Matthew Subscribers: speck, tobiaswiese, valerio.bozzolan, Matthew, Cigaryno Maniphest Tasks: T15591 Differential Revision: https://we.phorge.it/D25376 --- .../harbormaster/editor/HarbormasterBuildPlanEditEngine.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/applications/harbormaster/editor/HarbormasterBuildPlanEditEngine.php b/src/applications/harbormaster/editor/HarbormasterBuildPlanEditEngine.php index c0fa80d71b..b7d73f238b 100644 --- a/src/applications/harbormaster/editor/HarbormasterBuildPlanEditEngine.php +++ b/src/applications/harbormaster/editor/HarbormasterBuildPlanEditEngine.php @@ -103,7 +103,7 @@ final class HarbormasterBuildPlanEditEngine $key); $behavior_option = $object->getPlanProperty($storage_key); - if (!strlen($behavior_option)) { + if (!phutil_nonempty_string($behavior_option)) { $behavior_option = $behavior->getPlanOption($object)->getKey(); } From a2e8ab3180703305026da92f075c141537cfe5a1 Mon Sep 17 00:00:00 2001 From: Andre Klapper Date: Fri, 11 Aug 2023 21:01:19 +0200 Subject: [PATCH 05/93] Fix PHP 8.1 "strlen(null)" exception adding a "Drydock: Run Command" build step in Harbormaster Summary: `strlen()` was used in Phabricator to check if a generic value is a non-empty string. This behavior is deprecated since PHP 8.1. Phorge adopts `phutil_nonempty_string()` as a replacement. Note: this may highlight other absurd input values that might be worth correcting instead of just ignoring. If phutil_nonempty_string() throws an exception in your instance, report it to Phorge to evaluate and fix that specific corner case. ``` EXCEPTION: (RuntimeException) strlen(): Passing null to parameter #1 ($string) of type string is deprecated at [/src/error/PhutilErrorHandler.php:261] arcanist(head=customOAuthUrlencodeNull, ref.master=788098096e11, ref.customOAuthUrlencodeNull=4f0f2043b7e9), phorge(head=master, ref.master=226f3150933d) #0 <#2> PhutilErrorHandler::handleError(integer, string, string, integer) called at [/src/applications/harbormaster/controller/HarbormasterStepEditController.php:142] ``` Closes T15592 Test Plan: Add a build step for an existing Harbormaster Build Plan, see that page `New Step: Drydock: Run Command` is correctly rendered at `/harbormaster/step/new/1/HarbormasterDrydockCommandBuildStepImplementation/` Reviewers: O1 Blessed Committers, Matthew Reviewed By: O1 Blessed Committers, Matthew Subscribers: speck, tobiaswiese, valerio.bozzolan, Matthew, Cigaryno Maniphest Tasks: T15592 Differential Revision: https://we.phorge.it/D25377 --- .../harbormaster/controller/HarbormasterStepEditController.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/applications/harbormaster/controller/HarbormasterStepEditController.php b/src/applications/harbormaster/controller/HarbormasterStepEditController.php index 8cd91bb5a4..a420d02627 100644 --- a/src/applications/harbormaster/controller/HarbormasterStepEditController.php +++ b/src/applications/harbormaster/controller/HarbormasterStepEditController.php @@ -139,7 +139,7 @@ final class HarbormasterStepEditController ->setUser($viewer); $instructions = $implementation->getEditInstructions(); - if (strlen($instructions)) { + if (phutil_nonempty_string($instructions)) { $form->appendRemarkupInstructions($instructions); } From 98dfac53ba721467a32b96641f3a18d428fb5441 Mon Sep 17 00:00:00 2001 From: Andre Klapper Date: Fri, 11 Aug 2023 21:02:44 +0200 Subject: [PATCH 06/93] Fix PHP 8.1 "strlen(null)" exceptions blocking account registration with custom OAuth provider after redirect Summary: `strlen()` was used in Phabricator to check if a generic value is a non-empty string. This behavior is deprecated since PHP 8.1. Phorge adopts `phutil_nonempty_string()` as a replacement. Note: this may highlight other absurd input values that might be worth correcting instead of just ignoring. If phutil_nonempty_string() throws an exception in your instance, report it to Phorge to evaluate and fix that specific corner case. ``` EXCEPTION: (RuntimeException) strlen(): Passing null to parameter #1 ($string) of type string is deprecated at [/src/error/PhutilErrorHandler.php:261] arcanist(), ava(), phorge(), wmf-ext-misc() #0 <#2> PhutilErrorHandler::handleError(integer, string, string, integer) called at [/applications/auth/provider/PhabricatorOAuth1AuthProvider.php:70] ``` ``` EXCEPTION: (RuntimeException) strlen(): Passing null to parameter #1 ($string) of type string is deprecated at [/src/error/PhutilErrorHandler.php:261] arcanist(), ava(), phorge(), wmf-ext-misc() #0 <#2> PhutilErrorHandler::handleError(integer, string, string, integer) called at [/applications/auth/view/PhabricatorAuthAccountView.php:32] ``` Closes T15590 Test Plan: * As an admin, set up custom "MediaWiki" OAuth provider from from https://gitlab.wikimedia.org/-/ide/project/repos/phabricator/extensions/edit/wmf/stable/-/src/oauth/ * As an admin, apply D25373 * As a user, go to `/auth/login/mediawiki:whatever/` * Select login button * Allow authentication on third-party site * Get redirected to Phorge instance Phorge user account registration page "Create a New Account" at `/auth/register/abcdefghijklmnopqrstuvwxyz0123456/` now renders as expected, instead of displaying errors only. Reviewers: O1 Blessed Committers, Matthew Reviewed By: O1 Blessed Committers, Matthew Subscribers: speck, tobiaswiese, valerio.bozzolan, Matthew, Cigaryno Maniphest Tasks: T15590 Differential Revision: https://we.phorge.it/D25375 --- .../auth/provider/PhabricatorOAuth1AuthProvider.php | 2 +- .../auth/view/PhabricatorAuthAccountView.php | 9 +++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/applications/auth/provider/PhabricatorOAuth1AuthProvider.php b/src/applications/auth/provider/PhabricatorOAuth1AuthProvider.php index b1590b9c82..7133cff042 100644 --- a/src/applications/auth/provider/PhabricatorOAuth1AuthProvider.php +++ b/src/applications/auth/provider/PhabricatorOAuth1AuthProvider.php @@ -67,7 +67,7 @@ abstract class PhabricatorOAuth1AuthProvider } $denied = $request->getStr('denied'); - if (strlen($denied)) { + if ($denied) { // Twitter indicates that the user cancelled the login attempt by // returning "denied" as a parameter. throw new PhutilAuthUserAbortedException(); diff --git a/src/applications/auth/view/PhabricatorAuthAccountView.php b/src/applications/auth/view/PhabricatorAuthAccountView.php index 9746be7841..f903f45d26 100644 --- a/src/applications/auth/view/PhabricatorAuthAccountView.php +++ b/src/applications/auth/view/PhabricatorAuthAccountView.php @@ -29,13 +29,14 @@ final class PhabricatorAuthAccountView extends AphrontView { $realname = $account->getRealName(); $use_name = null; - if (strlen($dispname)) { + if (phutil_nonempty_string($dispname)) { $use_name = $dispname; - } else if (strlen($username) && strlen($realname)) { + } else if (phutil_nonempty_string($username) && + phutil_nonempty_string($realname)) { $use_name = $username.' ('.$realname.')'; - } else if (strlen($username)) { + } else if (phutil_nonempty_string($username)) { $use_name = $username; - } else if (strlen($realname)) { + } else if (phutil_nonempty_string($realname)) { $use_name = $realname; } From e8ea7a4a3697db4d0d8d36edfce57d0f06c6fd15 Mon Sep 17 00:00:00 2001 From: Steve Campbell Date: Sat, 12 Aug 2023 08:37:24 +0100 Subject: [PATCH 07/93] Fix PHP 8.1 issue in DifferentialChangeset getOldStatePathVector() Summary: The DifferentialChangeset getOldStatePathVector() method assumes oldFile and filename are set. This worked under PHP <= 8.0, but fails for PHP >= 8.1 with error messsage ``` strlen(): Passing null to parameter #1 ($string) of type string is deprecated ``` Fixes T15517 Test Plan: Create a diff in which a new file is added. This file will have oldFile NULL and filename a string. View the diff https://my.phorge.site/D1234 Reviewers: O1 Blessed Committers, Matthew Reviewed By: O1 Blessed Committers, Matthew Subscribers: speck, tobiaswiese, valerio.bozzolan, Matthew, Cigaryno Maniphest Tasks: T15517 Differential Revision: https://we.phorge.it/D25323 --- src/__phutil_library_map__.php | 2 ++ .../storage/DifferentialChangeset.php | 10 ++++++---- .../__tests__/DifferentialChangesetTestCase.php | 16 ++++++++++++++++ 3 files changed, 24 insertions(+), 4 deletions(-) create mode 100644 src/applications/differential/storage/__tests__/DifferentialChangesetTestCase.php diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php index 213b6cf6b1..d223f47515 100644 --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -488,6 +488,7 @@ phutil_register_library_map(array( 'DifferentialChangesetRenderer' => 'applications/differential/render/DifferentialChangesetRenderer.php', 'DifferentialChangesetSearchConduitAPIMethod' => 'applications/differential/conduit/DifferentialChangesetSearchConduitAPIMethod.php', 'DifferentialChangesetSearchEngine' => 'applications/differential/query/DifferentialChangesetSearchEngine.php', + 'DifferentialChangesetTestCase' => 'applications/differential/storage/__tests__/DifferentialChangesetTestCase.php', 'DifferentialChangesetTestRenderer' => 'applications/differential/render/DifferentialChangesetTestRenderer.php', 'DifferentialChangesetTwoUpRenderer' => 'applications/differential/render/DifferentialChangesetTwoUpRenderer.php', 'DifferentialChangesetTwoUpTestRenderer' => 'applications/differential/render/DifferentialChangesetTwoUpTestRenderer.php', @@ -6501,6 +6502,7 @@ phutil_register_library_map(array( 'DifferentialChangesetRenderer' => 'Phobject', 'DifferentialChangesetSearchConduitAPIMethod' => 'PhabricatorSearchEngineAPIMethod', 'DifferentialChangesetSearchEngine' => 'PhabricatorApplicationSearchEngine', + 'DifferentialChangesetTestCase' => 'PhabricatorTestCase', 'DifferentialChangesetTestRenderer' => 'DifferentialChangesetRenderer', 'DifferentialChangesetTwoUpRenderer' => 'DifferentialChangesetHTMLRenderer', 'DifferentialChangesetTwoUpTestRenderer' => 'DifferentialChangesetTestRenderer', diff --git a/src/applications/differential/storage/DifferentialChangeset.php b/src/applications/differential/storage/DifferentialChangeset.php index 770a49e411..d92b27e574 100644 --- a/src/applications/differential/storage/DifferentialChangeset.php +++ b/src/applications/differential/storage/DifferentialChangeset.php @@ -325,14 +325,16 @@ final class DifferentialChangeset public function getOldStatePathVector() { $path = $this->getOldFile(); - if (!strlen($path)) { + if (!phutil_nonempty_string($path)) { $path = $this->getFilename(); } - $path = trim($path, '/'); - $path = explode('/', $path); + if (!phutil_nonempty_string($path)) { + return null; + } - return $path; + $path = trim($path, '/'); + return explode('/', $path); } public function getNewStatePathVector() { diff --git a/src/applications/differential/storage/__tests__/DifferentialChangesetTestCase.php b/src/applications/differential/storage/__tests__/DifferentialChangesetTestCase.php new file mode 100644 index 0000000000..435b77ee87 --- /dev/null +++ b/src/applications/differential/storage/__tests__/DifferentialChangesetTestCase.php @@ -0,0 +1,16 @@ +getOldStatePathVector(); + $this->assertTrue(true, 'getOldStatePathVector did not throw an error'); + } catch (Throwable $ex) { + $this->assertTrue(false, + 'getOldStatePathVector threw an exception:'.$ex->getMessage()); + } + } + +} From bcfcd9acfc12fdf8ca3bf0e2c89651ba6d159b17 Mon Sep 17 00:00:00 2001 From: Aviv Eyal Date: Mon, 24 Jul 2023 06:20:48 -0700 Subject: [PATCH 08/93] Unify type-checking for `setHref()` type methods Summary: Adopt `PhutilURI::checkHrefType()` to unify type-check of some PHUI objects. Ref T15316. Depends on D25356. Test Plan: In production. Reviewers: O1 Blessed Committers, valerio.bozzolan Reviewed By: O1 Blessed Committers, valerio.bozzolan Subscribers: speck, tobiaswiese, valerio.bozzolan, Matthew, Cigaryno Maniphest Tasks: T15316 Differential Revision: https://we.phorge.it/D25357 --- src/view/phui/PHUIObjectItemView.php | 38 ++-------------------------- src/view/phui/PHUITagView.php | 13 ++-------- 2 files changed, 4 insertions(+), 47 deletions(-) diff --git a/src/view/phui/PHUIObjectItemView.php b/src/view/phui/PHUIObjectItemView.php index 600db9f3b7..527bd51b38 100644 --- a/src/view/phui/PHUIObjectItemView.php +++ b/src/view/phui/PHUIObjectItemView.php @@ -90,11 +90,7 @@ final class PHUIObjectItemView extends AphrontTagView { * @return self */ public function setHref($href) { - - // We have not a very clear idea about what this method should receive - // So, let's log alien stuff for some time - // https://we.phorge.it/T15316 - self::requireValidHref($href, 'href'); + PhutilURI::checkHrefType($href); $this->href = $href; return $this; @@ -161,11 +157,7 @@ final class PHUIObjectItemView extends AphrontTagView { * @return self */ public function setImageHref($image_href) { - - // We have not a very clear idea about what this method should receive - // So, let's log alien stuff for some time - // https://we.phorge.it/T15316 - self::requireValidHref($image_href, 'image_href'); + PhutilURI::checkHrefType($image_href); $this->imageHref = $image_href; return $this; @@ -929,30 +921,4 @@ final class PHUIObjectItemView extends AphrontTagView { return javelin_tag('span', $options, ''); } - - /** - * Receive a href attribute and check if it has expected values - * - * TODO: Feel free to remove after 2023, if no more new reports arrive. - * - * https://we.phorge.it/T15316 - * - * @param mixed $href Value to be checked - * @param string $variable_name Human reference - */ - private static function requireValidHref($href, $variable_name) { - - // We have not a very clear idea about what a "href" should be - if (is_object($href) && !($href instanceof PhutilURI)) { - - // We log stuff with a kind stack trace - phlog(new Exception(pht( - 'The variable %s received an unexpected type: %s. '. - 'Please share this stack trace as comment in Task %s', - $variable_name, - get_class($href), - 'https://we.phorge.it/T15316'))); - } - } - } diff --git a/src/view/phui/PHUITagView.php b/src/view/phui/PHUITagView.php index dc837c7156..c36fbab36b 100644 --- a/src/view/phui/PHUITagView.php +++ b/src/view/phui/PHUITagView.php @@ -103,20 +103,11 @@ final class PHUITagView extends AphrontTagView { /** * Set the href attribute * - * @param string|null $href + * @param string|PhutilURI|null $href * @return self */ public function setHref($href) { - - // We have not a very clear idea about what this method should receive - // We suspect that PhutilURI should be allowed... but let's log everything! - // https://we.phorge.it/T15316 - if (is_object($href)) { - phlog(sprintf( - 'Received unexpected type for href: %s. '. - 'Please paste this log as comment in https://we.phorge.it/T15316', - get_class($href))); - } + PhutilURI::checkHrefType($href); $this->href = $href; return $this; From 7040bd525764832bc805b595e8505d9b466f7ae5 Mon Sep 17 00:00:00 2001 From: Andre Klapper Date: Tue, 15 Aug 2023 10:15:09 +0200 Subject: [PATCH 09/93] Fix PHP 8.1 "strlen(null)" exception adding "Build with Buildkite" build step in Harbormaster Summary: `strlen()` was used in Phabricator to check if a generic value is a non-empty string. This behavior is deprecated since PHP 8.1. Phorge adopts `phutil_nonempty_string()` as a replacement. Note: this may highlight other absurd input values that might be worth correcting instead of just ignoring. If phutil_nonempty_string() throws an exception in your instance, report it to Phorge to evaluate and fix that specific corner case. ``` EXCEPTION: (RuntimeException) strlen(): Passing null to parameter #1 ($string) of type string is deprecated at [/src/error/PhutilErrorHandler.php:261] arcanist(head=customOAuthUrlencodeNull, ref.master=788098096e11, ref.customOAuthUrlencodeNull=4f0f2043b7e9), phorge(head=master, ref.master=226f3150933d) #0 <#2> PhutilErrorHandler::handleError(integer, string, string, integer) called at [/src/infrastructure/customfield/standard/PhabricatorStandardCustomField.php:271] ``` Closes T15594 Test Plan: Add a build step in Harbormaster, select "Interacting with External Build Systems > Build with Buildkite" at `/harbormaster/step/new/1/HarbormasterBuildkiteBuildStepImplementation/`, select the "Create Build Step" button. Page now shows several expected error messages (API Token is required; Organization Name is required; etc) instead of a PHP error. Reviewers: O1 Blessed Committers, Matthew Reviewed By: O1 Blessed Committers, Matthew Subscribers: speck, tobiaswiese, valerio.bozzolan, Matthew, Cigaryno Maniphest Tasks: T15594 Differential Revision: https://we.phorge.it/D25379 --- .../customfield/standard/PhabricatorStandardCustomField.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/infrastructure/customfield/standard/PhabricatorStandardCustomField.php b/src/infrastructure/customfield/standard/PhabricatorStandardCustomField.php index 373aa9b66a..0c4ea452a2 100644 --- a/src/infrastructure/customfield/standard/PhabricatorStandardCustomField.php +++ b/src/infrastructure/customfield/standard/PhabricatorStandardCustomField.php @@ -268,7 +268,7 @@ abstract class PhabricatorStandardCustomField public function readValueFromRequest(AphrontRequest $request) { $value = $request->getStr($this->getFieldKey()); - if (!strlen($value)) { + if (!phutil_nonempty_string($value)) { $value = null; } $this->setFieldValue($value); From 3f5fcdf4ddd8e527bf632bc90d3822ec2d824cd3 Mon Sep 17 00:00:00 2001 From: bob Date: Mon, 14 Aug 2023 11:05:11 +0200 Subject: [PATCH 10/93] Fix icon background color when using Dark Mode Summary: This CSS fix replaces the hard coded background gradient (white) value of icons when using Dark Mode. Now the "Choose User Icon" popup has visible icons. | Before | After | |---------|---------| |{F331622}|{F331623}| Ref T15056 Test Plan: - Flush all Phorge caches - Sign in - Go to user's Settings > Display Preferences and select the Accessibility (user interface) "Dark Mode". - Go to user's profile, edit profile and click on Choose icon. - Check that now the icons in "Choose User Icon" are visible. - Do these steps for each user interface theme in order to check against regression. Reviewers: O1 Blessed Committers, Matthew, valerio.bozzolan Reviewed By: O1 Blessed Committers, Matthew, valerio.bozzolan Subscribers: speck, tobiaswiese, valerio.bozzolan, Matthew, Cigaryno Maniphest Tasks: T15056 Differential Revision: https://we.phorge.it/D25384 --- resources/celerity/map.php | 4 ++-- webroot/rsrc/css/phui/phui-icon-set-selector.css | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/resources/celerity/map.php b/resources/celerity/map.php index 3fc6387e77..c78bf06e59 100644 --- a/resources/celerity/map.php +++ b/resources/celerity/map.php @@ -160,7 +160,7 @@ return array( 'rsrc/css/phui/phui-head-thing.css' => 'd7f293df', 'rsrc/css/phui/phui-header-view.css' => '36c86a58', 'rsrc/css/phui/phui-hovercard.css' => '39fd2e14', - 'rsrc/css/phui/phui-icon-set-selector.css' => '7aa5f3ec', + 'rsrc/css/phui/phui-icon-set-selector.css' => '19e0253b', 'rsrc/css/phui/phui-icon.css' => '084ac612', 'rsrc/css/phui/phui-image-mask.css' => '62c7f4d2', 'rsrc/css/phui/phui-info-view.css' => 'a10a909b', @@ -856,7 +856,7 @@ return array( 'phui-hovercard' => '6199f752', 'phui-hovercard-list' => 'de4b4919', 'phui-hovercard-view-css' => '39fd2e14', - 'phui-icon-set-selector-css' => '7aa5f3ec', + 'phui-icon-set-selector-css' => '19e0253b', 'phui-icon-view-css' => '084ac612', 'phui-image-mask-css' => '62c7f4d2', 'phui-info-view-css' => 'a10a909b', diff --git a/webroot/rsrc/css/phui/phui-icon-set-selector.css b/webroot/rsrc/css/phui/phui-icon-set-selector.css index c66c2a6e55..f3bc1b9685 100644 --- a/webroot/rsrc/css/phui/phui-icon-set-selector.css +++ b/webroot/rsrc/css/phui/phui-icon-set-selector.css @@ -3,8 +3,8 @@ */ button.icon-button { - background-color: #F7F7F9; - background-image: linear-gradient(to bottom, #ffffff, #f1f0f1); + background-image: linear-gradient(to bottom, + {$lightgreybackground}, {$greybackground}); border: 1px solid rgba({$alphablue},.2); color: {$darkgreytext}; position: relative; From 29493f8a5c950548f3b70843c45cb320dad42cde Mon Sep 17 00:00:00 2001 From: Andre Klapper Date: Tue, 15 Aug 2023 16:18:28 +0200 Subject: [PATCH 11/93] Fix PHP 8.1 "strlen(null)" exception listing >100 task search results Summary: `strlen()` was used in Phabricator to check if a generic value is a non-empty string. This behavior is deprecated since PHP 8.1. Phorge adopts `phutil_nonempty_string()` as a replacement. Note: this may highlight other absurd input values that might be worth correcting instead of just ignoring. If phutil_nonempty_string() throws an exception in your instance, report it to Phorge to evaluate and fix that specific corner case. ``` EXCEPTION: (RuntimeException) strlen(): Passing null to parameter #1 ($string) of type string is deprecated at [/src/error/PhutilErrorHandler.php:261] arcanist(head=master, ref.master=df6c315ace5f), phorge(head=master, ref.master=7040bd525764) #0 <#2> PhutilErrorHandler::handleError(integer, string, string, integer) called at [/src/applications/maniphest/query/ManiphestTaskQuery.php:1039] ``` Closes T15604 Test Plan: Have more than 100 tasks, run a broad search with more than 100 results, try to go to next page of results. Reviewers: O1 Blessed Committers, valerio.bozzolan Reviewed By: O1 Blessed Committers, valerio.bozzolan Subscribers: tobiaswiese, valerio.bozzolan, Matthew, Cigaryno Maniphest Tasks: T15604 Differential Revision: https://we.phorge.it/D25392 --- src/applications/maniphest/query/ManiphestTaskQuery.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/applications/maniphest/query/ManiphestTaskQuery.php b/src/applications/maniphest/query/ManiphestTaskQuery.php index 9e58728cff..8bbf976564 100644 --- a/src/applications/maniphest/query/ManiphestTaskQuery.php +++ b/src/applications/maniphest/query/ManiphestTaskQuery.php @@ -1036,7 +1036,7 @@ final class ManiphestTaskQuery extends PhabricatorCursorPagedPolicyAwareQuery { $parts[] = null; } - if (!strlen($parts[1])) { + if (!phutil_nonempty_string($parts[1])) { $parts[1] = null; } From 9fa9aa30b940e640d847b7603218af4baf48e15d Mon Sep 17 00:00:00 2001 From: Andre Klapper Date: Wed, 16 Aug 2023 13:11:56 +0200 Subject: [PATCH 12/93] Fix PHP 8.1 "strlen(null)" exception on "Link External Account" page at login Summary: `strlen()` was used in Phabricator to check if a generic value is a non-empty string. This behavior is deprecated since PHP 8.1. Phorge adopts `phutil_nonempty_string()` as a replacement. Note: this may highlight other absurd input values that might be worth correcting instead of just ignoring. If phutil_nonempty_string() throws an exception in your instance, report it to Phorge to evaluate and fix that specific corner case. ``` EXCEPTION: (RuntimeException) strlen(): Passing null to parameter #1 ($string) of type string is deprecated at [/src/error/PhutilErrorHandler.php:261] arcanist(), phorge() #0 <#2> PhutilErrorHandler::handleError(integer, string, string, integer) called at [/applications/auth/controller/PhabricatorAuthSetExternalController.php:43] ``` Closes T15606 Test Plan: Follow steps in T15606; page `/auth/external/` displays as expected the content: "Link External Account - You can link your Phabricator account to an external account to allow you to log in more easily in the future. To continue, choose an account to link below. If you prefer not to link your account, you can skip this step." and the "Link External Account" button. Reviewers: O1 Blessed Committers, avivey Reviewed By: O1 Blessed Committers, avivey Subscribers: avivey, tobiaswiese, valerio.bozzolan, Matthew, Cigaryno Maniphest Tasks: T15606 Differential Revision: https://we.phorge.it/D25395 --- .../auth/controller/PhabricatorAuthSetExternalController.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/applications/auth/controller/PhabricatorAuthSetExternalController.php b/src/applications/auth/controller/PhabricatorAuthSetExternalController.php index 8b0a44b9dc..2a8bbda7df 100644 --- a/src/applications/auth/controller/PhabricatorAuthSetExternalController.php +++ b/src/applications/auth/controller/PhabricatorAuthSetExternalController.php @@ -40,7 +40,7 @@ final class PhabricatorAuthSetExternalController $text = PhabricatorAuthMessage::loadMessageText( $viewer, PhabricatorAuthLinkMessageType::MESSAGEKEY); - if (!strlen($text)) { + if (!phutil_nonempty_string($text)) { $text = pht( 'You can link your %s account to an external account to '. 'allow you to log in more easily in the future. To continue, choose '. From a5d8b2d5cfd6e809f82556c9f1462ae0035e2279 Mon Sep 17 00:00:00 2001 From: bob Date: Thu, 17 Aug 2023 10:16:24 +0200 Subject: [PATCH 13/93] Fix a PHP 8.1 deprecated use of preg_match with a NULL argument Summary: These calls are preventing users to browse subversion/mercurial repositories in PHP 8.1+. Indeed, a similar bug affecting git repositories was already addressed in another commit (rP6b8ec50148909938850b5acfd11725ae23a8e31b). This commit harmonize both DiffusionSvnRequest and DiffusionMercurialRequest with DiffusionGitRequest Fix T15607 Test Plan: - Sign in - Open a diffusion SVN/Mercurial repository - You should not get a RuntimeException concerning this preg_match call Reviewers: O1 Blessed Committers, Sten, valerio.bozzolan Reviewed By: O1 Blessed Committers, Sten, valerio.bozzolan Subscribers: Sten, tobiaswiese, valerio.bozzolan, Matthew, Cigaryno Maniphest Tasks: T15607 Differential Revision: https://we.phorge.it/D25397 --- .../diffusion/request/DiffusionMercurialRequest.php | 5 +++-- src/applications/diffusion/request/DiffusionSvnRequest.php | 3 +++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/applications/diffusion/request/DiffusionMercurialRequest.php b/src/applications/diffusion/request/DiffusionMercurialRequest.php index b626d62750..676dc097f7 100644 --- a/src/applications/diffusion/request/DiffusionMercurialRequest.php +++ b/src/applications/diffusion/request/DiffusionMercurialRequest.php @@ -3,6 +3,9 @@ final class DiffusionMercurialRequest extends DiffusionRequest { protected function isStableCommit($symbol) { + if ($symbol === null) { + return false; + } return preg_match('/^[a-f0-9]{40}\z/', $symbol); } @@ -10,11 +13,9 @@ final class DiffusionMercurialRequest extends DiffusionRequest { if ($this->branch) { return $this->branch; } - if ($this->repository) { return $this->repository->getDefaultBranch(); } - throw new Exception(pht('Unable to determine branch!')); } diff --git a/src/applications/diffusion/request/DiffusionSvnRequest.php b/src/applications/diffusion/request/DiffusionSvnRequest.php index 5f50366331..33fc3446f9 100644 --- a/src/applications/diffusion/request/DiffusionSvnRequest.php +++ b/src/applications/diffusion/request/DiffusionSvnRequest.php @@ -3,6 +3,9 @@ final class DiffusionSvnRequest extends DiffusionRequest { protected function isStableCommit($symbol) { + if ($symbol === null) { + return false; + } return preg_match('/^[1-9]\d*\z/', $symbol); } From 17befe9bca5b6df2a3f867f58aa9fb5d564ecd9b Mon Sep 17 00:00:00 2001 From: bob Date: Thu, 17 Aug 2023 10:31:33 +0200 Subject: [PATCH 14/93] Fix source code viewer background color when using Dark Mode in Diffusion Summary: This CSS fix replaces the hard coded white background value by the diff.background CSS variable. This is a proposal to address this issue but it may be a good idea to create a different CSS variable (for instance source.background) in order to avoid any potential side effect in the future. | Before | After | |---------|---------| |{F333617}|{F333618}| Fix : T15056 Test Plan: - Flush all Phorge caches - Sign in - Open a diffusion repository - Open any file - Check that viewer background color is consistent with the theme. Reviewers: O1 Blessed Committers, valerio.bozzolan Reviewed By: O1 Blessed Committers, valerio.bozzolan Subscribers: tobiaswiese, valerio.bozzolan, Matthew, Cigaryno Differential Revision: https://we.phorge.it/D25396 --- resources/celerity/map.php | 4 ++-- webroot/rsrc/css/layout/phabricator-source-code-view.css | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/resources/celerity/map.php b/resources/celerity/map.php index c78bf06e59..a1dd137919 100644 --- a/resources/celerity/map.php +++ b/resources/celerity/map.php @@ -121,7 +121,7 @@ return array( 'rsrc/css/fuel/fuel-handle-list.css' => '2c4cbeca', 'rsrc/css/fuel/fuel-map.css' => 'd6e31510', 'rsrc/css/fuel/fuel-menu.css' => '21f5d199', - 'rsrc/css/layout/phabricator-source-code-view.css' => '49656486', + 'rsrc/css/layout/phabricator-source-code-view.css' => 'e382316a', 'rsrc/css/phui/button/phui-button-bar.css' => 'a4aa75c4', 'rsrc/css/phui/button/phui-button-simple.css' => '1ff278aa', 'rsrc/css/phui/button/phui-button.css' => 'f9d0f9c8', @@ -805,7 +805,7 @@ return array( 'phabricator-search-results-css' => '9ea70ace', 'phabricator-shaped-request' => '995f5102', 'phabricator-slowvote-css' => '1694baed', - 'phabricator-source-code-view-css' => '49656486', + 'phabricator-source-code-view-css' => 'e382316a', 'phabricator-standard-page-view' => 'e08c7462', 'phabricator-textareautils' => 'f340a484', 'phabricator-title' => '43bc9360', diff --git a/webroot/rsrc/css/layout/phabricator-source-code-view.css b/webroot/rsrc/css/layout/phabricator-source-code-view.css index b16b158004..83cda98df4 100644 --- a/webroot/rsrc/css/layout/phabricator-source-code-view.css +++ b/webroot/rsrc/css/layout/phabricator-source-code-view.css @@ -16,7 +16,7 @@ white-space: pre-wrap; padding: 2px 8px 1px; width: 100%; - background: #ffffff; + background: {$diff.background}; } .phabricator-source-line { From 747d7db241612313fa0ed82eda6d63592988d459 Mon Sep 17 00:00:00 2001 From: bob Date: Thu, 17 Aug 2023 10:41:12 +0200 Subject: [PATCH 15/93] Fix a PHP 8.1/8.2 deprecated use of ltrim and rtrim with a NULL argument Summary: These calls were preventing notification servers configuration to be properly initialized. Indeed, PHP 8.X is stricter concerning This behavior is deprecated since PHP 8.1. Phorge adopts phutil_nonempty_string() as a replacement. Fix T15598 Test Plan: Sign in as an administrator, configure the notification server without filling admin path field, you shouldn't get both an RuntimeException and a warning indicating that Phorge is unable to connect to Notification Server but a message indicating that everything is fine. Reviewers: O1 Blessed Committers, valerio.bozzolan, avivey Reviewed By: O1 Blessed Committers, valerio.bozzolan, avivey Subscribers: avivey, Cigaryno, Matthew, valerio.bozzolan, tobiaswiese, speck Maniphest Tasks: T15598 Differential Revision: https://we.phorge.it/D25382 --- .../client/PhabricatorNotificationServerRef.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/applications/notification/client/PhabricatorNotificationServerRef.php b/src/applications/notification/client/PhabricatorNotificationServerRef.php index c5b0f2f8aa..03cd5de5d4 100644 --- a/src/applications/notification/client/PhabricatorNotificationServerRef.php +++ b/src/applications/notification/client/PhabricatorNotificationServerRef.php @@ -143,8 +143,10 @@ final class PhabricatorNotificationServerRef return ($this->type == 'admin'); } - public function getURI($to_path = null) { - $full_path = rtrim($this->getPath(), '/').'/'.ltrim($to_path, '/'); + public function getURI($to_path = '') { + $path = coalesce($this->path, ''); + $to_path = coalesce($to_path, ''); + $full_path = rtrim($path, '/').'/'.ltrim($to_path, '/'); $uri = id(new PhutilURI('http://'.$this->getHost())) ->setProtocol($this->getProtocol()) From 7cffe557ac2458022e2799693284c5495c5d5458 Mon Sep 17 00:00:00 2001 From: bob Date: Thu, 17 Aug 2023 13:16:50 +0200 Subject: [PATCH 16/93] Fix hovercard background color when using Dark Mode Summary: This CSS fix replaces the disabled hovercard hard coded white background color value by the page.content CSS variable. Fix : T15056 Test Plan: - Flush all Phorge caches - Sign in - Open any page including a reference to a closed manifest (https://we.phorge.it/D25395) - Mouve the mouse over the closed manifest reference - Check that hovercard background color is consistent with the theme. Reviewers: O1 Blessed Committers, valerio.bozzolan Reviewed By: O1 Blessed Committers, valerio.bozzolan Subscribers: tobiaswiese, valerio.bozzolan, Matthew, Cigaryno Differential Revision: https://we.phorge.it/D25402 --- webroot/rsrc/css/phui/phui-hovercard.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webroot/rsrc/css/phui/phui-hovercard.css b/webroot/rsrc/css/phui/phui-hovercard.css index ba8057d08d..43c6f66df9 100644 --- a/webroot/rsrc/css/phui/phui-hovercard.css +++ b/webroot/rsrc/css/phui/phui-hovercard.css @@ -113,7 +113,7 @@ } .hovercard-task-view .phui-oi-disabled.phui-workcard { - background-color: #fff; + background-color: {$page.content}; } .phui-hovercard-object-type { From 3a1f568974f7bddc4235d4bdc8337f4c8713f7a1 Mon Sep 17 00:00:00 2001 From: Andre Klapper Date: Thu, 17 Aug 2023 14:42:02 +0200 Subject: [PATCH 17/93] Fix typo "this this server" Summary: Closes T15611 Test Plan: Carefully read. Reviewers: O1 Blessed Committers, avivey Reviewed By: O1 Blessed Committers, avivey Subscribers: tobiaswiese, valerio.bozzolan, Matthew, Cigaryno Maniphest Tasks: T15611 Differential Revision: https://we.phorge.it/D25404 --- .../PhabricatorAuthProvidersGuidanceEngineExtension.php | 5 ++--- src/applications/phame/storage/PhameBlog.php | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/applications/auth/guidance/PhabricatorAuthProvidersGuidanceEngineExtension.php b/src/applications/auth/guidance/PhabricatorAuthProvidersGuidanceEngineExtension.php index d4d41f1d83..8d823f82c2 100644 --- a/src/applications/auth/guidance/PhabricatorAuthProvidersGuidanceEngineExtension.php +++ b/src/applications/auth/guidance/PhabricatorAuthProvidersGuidanceEngineExtension.php @@ -53,9 +53,8 @@ final class PhabricatorAuthProvidersGuidanceEngineExtension ->setMessage($message); } else { $message = pht( - 'Anyone who can browse to this this server will be able to '. - 'register an account. To add email domain restrictions, configure '. - '%s.', + 'Anyone who can browse to this server will be able to register '. + 'an account. To add email domain restrictions, configure %s.', $domains_link); $results[] = $this->newGuidance('core.auth.email-domains.off') diff --git a/src/applications/phame/storage/PhameBlog.php b/src/applications/phame/storage/PhameBlog.php index 587f5daea3..8ab5c2747e 100644 --- a/src/applications/phame/storage/PhameBlog.php +++ b/src/applications/phame/storage/PhameBlog.php @@ -154,7 +154,7 @@ final class PhameBlog extends PhameDAO $href = PhabricatorEnv::getProductionURI( '/config/edit/policy.allow-public/'); return pht( - 'For custom domains to work, this this server must be '. + 'For custom domains to work, this server must be '. 'configured to allow the public access policy. Configure this '. 'setting %s, or ask an administrator to configure this setting. '. 'The domain can be specified later once this setting has been '. From 761134a1a9fe2b2a74ede5705bd41edeb561965b Mon Sep 17 00:00:00 2001 From: Valerio Bozzolan Date: Fri, 18 Aug 2023 09:53:23 +0800 Subject: [PATCH 18/93] Line counters: do not wrap when over 999 on mobile Summary: | Before | After | |-----------|-----------| | {F335620} | {F335621} | Closes T15615 Test Plan: Create a very long Diff with soooo much lines (e.g. 1000+). Reduce the window and check that line numbers do not wrap anymore. Reviewers: O1 Blessed Committers, avivey Reviewed By: O1 Blessed Committers, avivey Subscribers: tobiaswiese, Matthew, Cigaryno Maniphest Tasks: T15615 Differential Revision: https://we.phorge.it/D25407 --- resources/celerity/map.php | 12 ++++++------ .../css/application/differential/changeset-view.css | 1 + 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/resources/celerity/map.php b/resources/celerity/map.php index a1dd137919..8f791cbeda 100644 --- a/resources/celerity/map.php +++ b/resources/celerity/map.php @@ -12,7 +12,7 @@ return array( 'core.pkg.css' => '1a5169fe', 'core.pkg.js' => '2eeda9e0', 'dark-console.pkg.js' => '187792c2', - 'differential.pkg.css' => '525f9a1d', + 'differential.pkg.css' => '2431def2', 'differential.pkg.js' => '46fcb3af', 'diffusion.pkg.css' => '42c75c37', 'diffusion.pkg.js' => '78c9885d', @@ -63,7 +63,7 @@ return array( 'rsrc/css/application/diff/diff-tree-view.css' => 'e2d3e222', 'rsrc/css/application/diff/inline-comment-summary.css' => '81eb368d', 'rsrc/css/application/differential/add-comment.css' => '7e5900d9', - 'rsrc/css/application/differential/changeset-view.css' => '8b9caefe', + 'rsrc/css/application/differential/changeset-view.css' => '360630ff', 'rsrc/css/application/differential/core.css' => '7300a73e', 'rsrc/css/application/differential/phui-inline-comment.css' => 'a864426f', 'rsrc/css/application/differential/revision-comment.css' => '7dbc8d1d', @@ -560,7 +560,7 @@ return array( 'conpherence-transaction-css' => '3a3f5e7e', 'd3' => '9d068042', 'diff-tree-view-css' => 'e2d3e222', - 'differential-changeset-view-css' => '8b9caefe', + 'differential-changeset-view-css' => '360630ff', 'differential-core-view-css' => '7300a73e', 'differential-revision-add-comment-css' => '7e5900d9', 'differential-revision-comment-css' => '7dbc8d1d', @@ -1228,6 +1228,9 @@ return array( 'aphront-typeahead-control-css', 'phui-tag-view-css', ), + '360630ff' => array( + 'phui-inline-comment-view-css', + ), '3829a3cf' => array( 'javelin-behavior', 'javelin-uri', @@ -1702,9 +1705,6 @@ return array( 'javelin-dom', 'phabricator-busy', ), - '8b9caefe' => array( - 'phui-inline-comment-view-css', - ), '8badee71' => array( 'javelin-install', 'javelin-util', diff --git a/webroot/rsrc/css/application/differential/changeset-view.css b/webroot/rsrc/css/application/differential/changeset-view.css index 88bbcfa421..a127d14648 100644 --- a/webroot/rsrc/css/application/differential/changeset-view.css +++ b/webroot/rsrc/css/application/differential/changeset-view.css @@ -183,6 +183,7 @@ should always have a boring grey background. */ cursor: pointer; border-right: 1px solid {$thinblueborder}; overflow: hidden; + white-space: nowrap; } .differential-diff td + td.n { From 7f46a252f21e6dc21caba593440db4da13684dab Mon Sep 17 00:00:00 2001 From: bob Date: Fri, 18 Aug 2023 09:19:42 +0200 Subject: [PATCH 19/93] Fix a PHP 8.1/8.2 deprecated use of strlen a NULL argument Summary: This commit harmonizes PhabricatorNotificationServerRef's getURI and getWebsocketURI methods as discussed in D25382. Test Plan: This is hard to say since I didn't know how/when this function might be called. Reviewers: O1 Blessed Committers, valerio.bozzolan Reviewed By: O1 Blessed Committers, valerio.bozzolan Subscribers: tobiaswiese, valerio.bozzolan, Matthew, Cigaryno Differential Revision: https://we.phorge.it/D25401 --- .../notification/client/PhabricatorNotificationServerRef.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/applications/notification/client/PhabricatorNotificationServerRef.php b/src/applications/notification/client/PhabricatorNotificationServerRef.php index 03cd5de5d4..2fe903fdba 100644 --- a/src/applications/notification/client/PhabricatorNotificationServerRef.php +++ b/src/applications/notification/client/PhabricatorNotificationServerRef.php @@ -161,9 +161,9 @@ final class PhabricatorNotificationServerRef return $uri; } - public function getWebsocketURI($to_path = null) { + public function getWebsocketURI($to_path = '') { $instance = PhabricatorEnv::getEnvConfig('cluster.instance'); - if (strlen($instance)) { + if (phutil_nonempty_string($instance)) { $to_path = $to_path.'~'.$instance.'/'; } From 0ef08baf64527d3c31e5cc2e1da4b4318309c45a Mon Sep 17 00:00:00 2001 From: bob Date: Fri, 18 Aug 2023 09:20:23 +0200 Subject: [PATCH 20/93] Fix a PHP 8.1 deprecated use of strlen with a NULL argument Summary: This strlen() call was preventing a new Phorge instance to be deployed/configured. Indeed, on a fresh instance, configuration's "base-uri" key may not be defined witch lead to a Runtime Exception. Using strlen() to check string validity is deprecated since PHP 8.1, phorge adopts phutil_nonempty_string() as a replacement. Note: this may highlight other absurd input values that might be worth correcting instead of just ignoring. If phutil_nonempty_string() throws an exception in your instance, report it to Phorge to evaluate and fix that specific corner case. Fix T15605 Test Plan: - Checkout a fresh Phorge local copy from official 'https://we.phorge.it/source/phorge.git' - Install/Configure local webserver/database - Open http://phorge.domain in you browser - Configure Phorge database (as requested by webpage) - Create Phorge database (as requested by webpage) - You should be able to reach administrator account page instead of getting a RuntimeException Reviewers: O1 Blessed Committers, valerio.bozzolan Reviewed By: O1 Blessed Committers, valerio.bozzolan Subscribers: tobiaswiese, valerio.bozzolan, Matthew, Cigaryno Maniphest Tasks: T15605 Differential Revision: https://we.phorge.it/D25394 --- .../config/check/PhabricatorWebServerSetupCheck.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/applications/config/check/PhabricatorWebServerSetupCheck.php b/src/applications/config/check/PhabricatorWebServerSetupCheck.php index cc9660325c..d46f808f58 100644 --- a/src/applications/config/check/PhabricatorWebServerSetupCheck.php +++ b/src/applications/config/check/PhabricatorWebServerSetupCheck.php @@ -23,7 +23,7 @@ final class PhabricatorWebServerSetupCheck extends PhabricatorSetupCheck { } $base_uri = PhabricatorEnv::getEnvConfig('phabricator.base-uri'); - if (!strlen($base_uri)) { + if (!$base_uri) { // If `phabricator.base-uri` is not set then we can't really do // anything. return; From d84dbf8e27ba845b1c29e885d600e7f1d2d7e815 Mon Sep 17 00:00:00 2001 From: Andre Klapper Date: Thu, 17 Aug 2023 17:27:21 +0200 Subject: [PATCH 21/93] Fix PHP 8.1 "strlen(null)" exception creating a Paste without content in Conduit paste.create Summary: `strlen()` was used in Phabricator to check if a generic value is a non-empty string. This behavior is deprecated since PHP 8.1. Phorge adopts `phutil_nonempty_string()` as a replacement. Note: this may highlight other absurd input values that might be worth correcting instead of just ignoring. If phutil_nonempty_string() throws an exception in your instance, report it to Phorge to evaluate and fix that specific corner case. ``` EXCEPTION: (RuntimeException) strlen(): Passing null to parameter #1 ($string) of type string is deprecated at [/src/error/PhutilErrorHandler.php:261] arcanist(head=master, ref.master=df6c315ace5f), phorge(head=thisThis, ref.master=7cffe557ac24, ref.thisThis=529790613a86) #0 <#2> PhutilErrorHandler::handleError(integer, string, string, integer) called at [/src/applications/paste/conduit/PasteCreateConduitAPIMethod.php:46] ``` Closes T15613 Test Plan: Create a paste in the deprecated API paste.create without content via Conduit. Shows `error_code ERR-NO-PASTE` as expected, and no exception. Reviewers: O1 Blessed Committers, valerio.bozzolan Reviewed By: O1 Blessed Committers, valerio.bozzolan Subscribers: tobiaswiese, valerio.bozzolan, Matthew, Cigaryno Maniphest Tasks: T15613 Differential Revision: https://we.phorge.it/D25405 --- src/applications/paste/conduit/PasteCreateConduitAPIMethod.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/applications/paste/conduit/PasteCreateConduitAPIMethod.php b/src/applications/paste/conduit/PasteCreateConduitAPIMethod.php index c62ecd0494..d55d184874 100644 --- a/src/applications/paste/conduit/PasteCreateConduitAPIMethod.php +++ b/src/applications/paste/conduit/PasteCreateConduitAPIMethod.php @@ -43,7 +43,7 @@ final class PasteCreateConduitAPIMethod extends PasteConduitAPIMethod { $title = $request->getValue('title'); $language = $request->getValue('language'); - if (!strlen($content)) { + if (!phutil_nonempty_string($content)) { throw new ConduitException('ERR-NO-PASTE'); } From 7c58ea140374fd17cc12d9ab068cde2579781832 Mon Sep 17 00:00:00 2001 From: Andre Klapper Date: Thu, 17 Aug 2023 17:42:24 +0200 Subject: [PATCH 22/93] Fix PHP 8.1 "strlen(null)" exception creating a Phriction doc without slug in Conduit Summary: `strlen()` was used in Phabricator to check if a generic value is a non-empty string. This behavior is deprecated since PHP 8.1. Phorge adopts `phutil_nonempty_string()` as a replacement. Note: this may highlight other absurd input values that might be worth correcting instead of just ignoring. If phutil_nonempty_string() throws an exception in your instance, report it to Phorge to evaluate and fix that specific corner case. ``` EXCEPTION: (RuntimeException) strlen(): Passing null to parameter #1 ($string) of type string is deprecated at [/src/error/PhutilErrorHandler.php:261] arcanist(head=master, ref.master=df6c315ace5f), phorge(head=master, ref.master=7cffe557ac24) #0 <#2> PhutilErrorHandler::handleError(integer, string, string, integer) called at [/src/applications/phriction/conduit/PhrictionCreateConduitAPIMethod.php:28] ``` Closes T15614 Test Plan: Create a Phriction document without slug via Conduit. Get an `EXCEPTION: (Exception) No such document.` instead of a `strlen()` exception. Reviewers: O1 Blessed Committers, valerio.bozzolan Reviewed By: O1 Blessed Committers, valerio.bozzolan Subscribers: tobiaswiese, valerio.bozzolan, Matthew, Cigaryno Maniphest Tasks: T15614 Differential Revision: https://we.phorge.it/D25406 --- .../phriction/conduit/PhrictionCreateConduitAPIMethod.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/applications/phriction/conduit/PhrictionCreateConduitAPIMethod.php b/src/applications/phriction/conduit/PhrictionCreateConduitAPIMethod.php index 300dbbfa80..61d3611faf 100644 --- a/src/applications/phriction/conduit/PhrictionCreateConduitAPIMethod.php +++ b/src/applications/phriction/conduit/PhrictionCreateConduitAPIMethod.php @@ -25,7 +25,7 @@ final class PhrictionCreateConduitAPIMethod extends PhrictionConduitAPIMethod { protected function execute(ConduitAPIRequest $request) { $slug = $request->getValue('slug'); - if (!strlen($slug)) { + if (!phutil_nonempty_string($slug)) { throw new Exception(pht('No such document.')); } $doc = id(new PhrictionDocumentQuery()) From ad0052fcd643cb6b88453a6c8a11b5593056e154 Mon Sep 17 00:00:00 2001 From: Aviv Eyal Date: Fri, 18 Aug 2023 02:00:06 -0700 Subject: [PATCH 23/93] Rebrand: Add "path" entries to PlatformSymbols Summary: Ref T15006. Change a few places that were mentioning `phabricator` path. Test Plan: Mk1 eyeball on each effected page. Reviewers: O1 Blessed Committers, valerio.bozzolan Reviewed By: O1 Blessed Committers, valerio.bozzolan Subscribers: speck, tobiaswiese, valerio.bozzolan, Matthew, Cigaryno Maniphest Tasks: T15006 Differential Revision: https://we.phorge.it/D25343 --- .../controller/PhabricatorDaemonLogViewController.php | 3 ++- .../controller/DiffusionRepositoryEditDeleteController.php | 3 ++- src/applications/metamta/PhabricatorMetaMTAWorker.php | 7 ++++--- .../repository/query/PhabricatorRepositoryQuery.php | 4 ++++ .../markup/markuprule/PhutilRemarkupEvalRule.php | 4 ++-- 5 files changed, 14 insertions(+), 7 deletions(-) diff --git a/src/applications/daemon/controller/PhabricatorDaemonLogViewController.php b/src/applications/daemon/controller/PhabricatorDaemonLogViewController.php index f4c7ba60c9..253a3d5190 100644 --- a/src/applications/daemon/controller/PhabricatorDaemonLogViewController.php +++ b/src/applications/daemon/controller/PhabricatorDaemonLogViewController.php @@ -171,7 +171,8 @@ final class PhabricatorDaemonLogViewController phutil_tag( 'tt', array(), - "phabricator/ $ ./bin/phd log --id {$id}")); + PlatformSymbols::getPlatformServerPath(). + " $ ./bin/phd log --id {$id}")); return $view; diff --git a/src/applications/diffusion/controller/DiffusionRepositoryEditDeleteController.php b/src/applications/diffusion/controller/DiffusionRepositoryEditDeleteController.php index 93fe70c0fe..72e18d17e8 100644 --- a/src/applications/diffusion/controller/DiffusionRepositoryEditDeleteController.php +++ b/src/applications/diffusion/controller/DiffusionRepositoryEditDeleteController.php @@ -28,7 +28,8 @@ final class DiffusionRepositoryEditDeleteController 'the command line:')) ->appendCommand( csprintf( - 'phabricator/ $ ./bin/remove destroy %R', + '%s $ ./bin/remove destroy %R', + PlatformSymbols::getPlatformServerPath(), $repository->getMonogram())) ->appendParagraph( pht( diff --git a/src/applications/metamta/PhabricatorMetaMTAWorker.php b/src/applications/metamta/PhabricatorMetaMTAWorker.php index dcc6a8dc5e..7d7c51f8b2 100644 --- a/src/applications/metamta/PhabricatorMetaMTAWorker.php +++ b/src/applications/metamta/PhabricatorMetaMTAWorker.php @@ -45,9 +45,10 @@ final class PhabricatorMetaMTAWorker public function renderForDisplay(PhabricatorUser $viewer) { return phutil_tag( 'pre', - array( - ), - 'phabricator/ $ ./bin/mail show-outbound --id '.$this->getTaskData()); + array(), + PlatformSymbols::getPlatformServerPath(). + ' $ ./bin/mail show-outbound --id '. + $this->getTaskData()); } } diff --git a/src/applications/repository/query/PhabricatorRepositoryQuery.php b/src/applications/repository/query/PhabricatorRepositoryQuery.php index 05b011e85a..17a46f7b62 100644 --- a/src/applications/repository/query/PhabricatorRepositoryQuery.php +++ b/src/applications/repository/query/PhabricatorRepositoryQuery.php @@ -62,6 +62,10 @@ final class PhabricatorRepositoryQuery $slugs = array(); foreach ($identifiers as $identifier) { + if ($identifier === null) { + continue; + } + if (ctype_digit((string)$identifier)) { $ids[$identifier] = $identifier; continue; diff --git a/src/infrastructure/markup/markuprule/PhutilRemarkupEvalRule.php b/src/infrastructure/markup/markuprule/PhutilRemarkupEvalRule.php index cb67041c62..a525924fff 100644 --- a/src/infrastructure/markup/markuprule/PhutilRemarkupEvalRule.php +++ b/src/infrastructure/markup/markuprule/PhutilRemarkupEvalRule.php @@ -68,11 +68,11 @@ final class PhutilRemarkupEvalRule extends PhutilRemarkupRule { 'platform' => array( 'server' => array( 'name' => PlatformSymbols::getPlatformServerName(), - 'path' => pht('phabricator/'), + 'path' => PlatformSymbols::getPlatformServerPath(), ), 'client' => array( 'name' => PlatformSymbols::getPlatformClientName(), - 'path' => pht('arcanist/'), + 'path' => PlatformSymbols::getPlatformClientPath(), ), ), ), From 6ec89e9f08668c950c6a7d80164bd822bd38b472 Mon Sep 17 00:00:00 2001 From: bob Date: Fri, 18 Aug 2023 12:48:02 +0200 Subject: [PATCH 24/93] Fix a PHP 8.1 deprecated use of strlen with a NULL argument Summary: With PHP 8.1+ it was not possible to view a commit from subversion repositories. Indeed, if the commit user and/or email is not properly defined, strlen(null) is called, causing a deprecation warning, elevated to exception. Using strlen() to check string validity is deprecated since PHP 8.1. Phorge adopts phutil_nonempty_string() as a replacement. Note: this may highlight other absurd input values that might be worth correcting instead of just ignoring. If phutil_nonempty_string() throws an exception in your instance, report it to Phorge to evaluate and fix that specific corner case. Fix T15609 Test Plan: - Apply D25397 and D25398 - Sign in - Open a diffusion SVN repository - Open a commit without user name and or email - You should not see the same Runtime Exception (unfortunately, there is another one as described in T15610) Reviewers: O1 Blessed Committers, valerio.bozzolan Reviewed By: O1 Blessed Committers, valerio.bozzolan Subscribers: tobiaswiese, valerio.bozzolan, Matthew, Cigaryno Maniphest Tasks: T15609 Differential Revision: https://we.phorge.it/D25399 --- src/applications/diffusion/data/DiffusionCommitRef.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/applications/diffusion/data/DiffusionCommitRef.php b/src/applications/diffusion/data/DiffusionCommitRef.php index 06dd4d5ffb..76c3371192 100644 --- a/src/applications/diffusion/data/DiffusionCommitRef.php +++ b/src/applications/diffusion/data/DiffusionCommitRef.php @@ -131,6 +131,8 @@ final class DiffusionCommitRef extends Phobject { } private function formatUser($name, $email) { + $name = coalesce($name, ''); + $email = coalesce($email, ''); if (strlen($name) && strlen($email)) { return "{$name} <{$email}>"; } else if (strlen($email)) { From 8876f75fbb9978f82040122660a7cabbc5358eb9 Mon Sep 17 00:00:00 2001 From: bob Date: Fri, 18 Aug 2023 15:49:32 +0200 Subject: [PATCH 25/93] Fix a PHP 8.1 deprecated use of strlen with a NULL argument Summary: This call is preventing users to browse Subversion repositories. Using strlen() to check string validity is deprecated since PHP 8.1, phorge adopts phutil_nonempty_string() as a replacement. Note: this may highlight other absurd input values that might be worth correcting instead of just ignoring. If phutil_nonempty_string() throws an exception in your instance, report it to Phorge to evaluate and fix that specific corner case. Fix T15608 Test Plan: - Sign in - Open a Diffusion SVN repository - You should see the repository instead of getting a Runtime Exception Reviewers: O1 Blessed Committers, Sten, avivey Reviewed By: O1 Blessed Committers, Sten, avivey Subscribers: Sten, tobiaswiese, valerio.bozzolan, Matthew, Cigaryno Maniphest Tasks: T15608 Differential Revision: https://we.phorge.it/D25398 --- .../diffusion/controller/DiffusionRepositoryController.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/applications/diffusion/controller/DiffusionRepositoryController.php b/src/applications/diffusion/controller/DiffusionRepositoryController.php index ad3518b81e..3ae237c22d 100644 --- a/src/applications/diffusion/controller/DiffusionRepositoryController.php +++ b/src/applications/diffusion/controller/DiffusionRepositoryController.php @@ -508,7 +508,7 @@ final class DiffusionRepositoryController extends DiffusionController { $repository_name = $repository->getName(); $branch_name = $drequest->getBranch(); - if (strlen($branch_name)) { + if (phutil_nonempty_string($branch_name)) { $repository_name .= ' ('.$branch_name.')'; } From 3cc5ee6a33dfdf8e1e8bfcc12b655ebd516b3e5b Mon Sep 17 00:00:00 2001 From: Valerio Bozzolan Date: Sat, 19 Aug 2023 00:02:14 +0800 Subject: [PATCH 26/93] Documentation: fix unexisting path sshd_config.phabricator.example Summary: Since the example file was renamed, this change makes the documentation consistent with it. Also we added exactly one-space somewhere, to create a super-satisfying indentation an example block. You're welcome. Ref T15006 Test Plan: Check that the documentation is at least 0.000001% better now. Reviewers: O1 Blessed Committers, avivey Reviewed By: O1 Blessed Committers, avivey Subscribers: tobiaswiese, Matthew, Cigaryno Maniphest Tasks: T15006 Differential Revision: https://we.phorge.it/D25410 --- src/docs/user/userguide/diffusion_hosting.diviner | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/docs/user/userguide/diffusion_hosting.diviner b/src/docs/user/userguide/diffusion_hosting.diviner index c8a1c26eed..0d84859082 100644 --- a/src/docs/user/userguide/diffusion_hosting.diviner +++ b/src/docs/user/userguide/diffusion_hosting.diviner @@ -360,13 +360,13 @@ be owned by `root`, and the script must have `755` permissions: ``` $ sudo chown root /path/to/somewhere/ $ sudo chown root /path/to/somewhere/phorge-ssh-hook.sh -$ sudo chmod 755 /path/to/somewhere/phorge-ssh-hook.sh +$ sudo chmod 755 /path/to/somewhere/phorge-ssh-hook.sh ``` If you don't do this, `sshd` will refuse to execute the hook. **Create `sshd_config` for Phorge**: Copy the template in -`phorge/resources/sshd/sshd_config.phabricator.example` to somewhere like +`phorge/resources/sshd/sshd_config.phorge.example` to somewhere like `/etc/ssh/sshd_config.phorge`. Open the file and edit the `AuthorizedKeysCommand`, From ba4b8cb1ae7d209caf6e2a209247e114262d0d15 Mon Sep 17 00:00:00 2001 From: Aviv Eyal Date: Fri, 18 Aug 2023 12:28:03 -0700 Subject: [PATCH 27/93] PHP 8 and Diviner Technical Documentation Summary: This also fixes the field Personal Settings > Display Preferences > Monospaced Font, when empty. Close T15621 Test Plan: Generate diviner stuff, navigate to the "Technical Documentation" section (In php 8.1+) Reviewers: O1 Blessed Committers, mturdus, valerio.bozzolan Reviewed By: O1 Blessed Committers, mturdus, valerio.bozzolan Subscribers: tobiaswiese, valerio.bozzolan, Matthew, Cigaryno Maniphest Tasks: T15621 Differential Revision: https://we.phorge.it/D25412 --- src/applications/diviner/storage/DivinerLiveSymbol.php | 2 +- .../settings/setting/PhabricatorMonospacedFontSetting.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/applications/diviner/storage/DivinerLiveSymbol.php b/src/applications/diviner/storage/DivinerLiveSymbol.php index d62e6a1e18..6477e00879 100644 --- a/src/applications/diviner/storage/DivinerLiveSymbol.php +++ b/src/applications/diviner/storage/DivinerLiveSymbol.php @@ -172,7 +172,7 @@ final class DivinerLiveSymbol extends DivinerDAO public function getTitle() { $title = parent::getTitle(); - if (!strlen($title)) { + if (!phutil_nonempty_string($title)) { $title = $this->getName(); } diff --git a/src/applications/settings/setting/PhabricatorMonospacedFontSetting.php b/src/applications/settings/setting/PhabricatorMonospacedFontSetting.php index 2a96f5d95f..5cfbec1b26 100644 --- a/src/applications/settings/setting/PhabricatorMonospacedFontSetting.php +++ b/src/applications/settings/setting/PhabricatorMonospacedFontSetting.php @@ -25,7 +25,7 @@ final class PhabricatorMonospacedFontSetting } public function validateTransactionValue($value) { - if (!strlen($value)) { + if (!phutil_nonempty_string($value)) { return; } From 9b105c8e9e54a863a5e92f84c6f27af846647676 Mon Sep 17 00:00:00 2001 From: Andre Klapper Date: Fri, 18 Aug 2023 18:39:59 +0200 Subject: [PATCH 28/93] Fix PHP 8.1 "strlen(null)" exceptions importing ICS file into calendar Summary: `strlen()` was used in Phabricator to check if a generic value is a non-empty string. This behavior is deprecated since PHP 8.1. Phorge adopts `phutil_nonempty_string()` as a replacement. Note: this may highlight other absurd input values that might be worth correcting instead of just ignoring. If phutil_nonempty_string() throws an exception in your instance, report it to Phorge to evaluate and fix that specific corner case. ``` EXCEPTION: (RuntimeException) strlen(): Passing null to parameter #1 ($string) of type string is deprecated at [/src/error/PhutilErrorHandler.php:261] arcanist(head=master, ref.master=df6c315ace5f), phorge(head=importICSCalendar, ref.master=3cc5ee6a33df, ref.importICSCalendar=3bd396120123) #0 <#2> PhutilErrorHandler::handleError(integer, string, string, integer) called at [/src/applications/calendar/import/PhabricatorCalendarImportEngine.php:459] ``` ``` EXCEPTION: (RuntimeException) strlen(): Passing null to parameter #1 ($string) of type string is deprecated at [/src/error/PhutilErrorHandler.php:261] arcanist(head=master, ref.master=df6c315ace5f), phorge(head=importICSCalendar, ref.master=3cc5ee6a33df, ref.importICSCalendar=3bd396120123) #0 <#2> PhutilErrorHandler::handleError(integer, string, string, integer) called at [/src/applications/calendar/import/PhabricatorCalendarImportEngine.php:450] ``` Closes T15620 Test Plan: * Revert rP02a4f8b0c8f1279fc0040ad8077942fd8b0d948b not to run into T15619 * Try to import an ICS file via `/calendar/import/edit/` * See that page `/calendar/import/4/` renders correctly in web browser and shows `Log Messages` and `Imported Events` as expected Reviewers: O1 Blessed Committers, valerio.bozzolan Reviewed By: O1 Blessed Committers, valerio.bozzolan Subscribers: tobiaswiese, valerio.bozzolan, Matthew, Cigaryno Maniphest Tasks: T15620 Differential Revision: https://we.phorge.it/D25411 --- .../calendar/import/PhabricatorCalendarImportEngine.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/applications/calendar/import/PhabricatorCalendarImportEngine.php b/src/applications/calendar/import/PhabricatorCalendarImportEngine.php index 35e94634fe..626757c61d 100644 --- a/src/applications/calendar/import/PhabricatorCalendarImportEngine.php +++ b/src/applications/calendar/import/PhabricatorCalendarImportEngine.php @@ -447,7 +447,7 @@ abstract class PhabricatorCalendarImportEngine private function getParentNodeUID(PhutilCalendarEventNode $node) { $recurrence_id = $node->getRecurrenceID(); - if (!strlen($recurrence_id)) { + if (!phutil_nonempty_string($recurrence_id)) { return null; } @@ -456,7 +456,7 @@ abstract class PhabricatorCalendarImportEngine private function getNodeInstanceEpoch(PhutilCalendarEventNode $node) { $instance_iso = $node->getRecurrenceID(); - if (strlen($instance_iso)) { + if (phutil_nonempty_string($instance_iso)) { $instance_datetime = PhutilCalendarAbsoluteDateTime::newFromISO8601( $instance_iso); $instance_epoch = $instance_datetime->getEpoch(); From beec08e0191386d73581862b4378a0282166345f Mon Sep 17 00:00:00 2001 From: Andre Klapper Date: Tue, 22 Aug 2023 11:07:02 +0200 Subject: [PATCH 29/93] Fix RuntimeException: min(): Array must contain at least one element Summary: Make sure that `$epochs[]` is never empty but contains `0` so `min($epochs)` will not complain. Closes T15623 Test Plan: Carefully read the code (as I am unaware of reproduction steps). Reviewers: O1 Blessed Committers, avivey Reviewed By: O1 Blessed Committers, avivey Subscribers: tobiaswiese, valerio.bozzolan, Matthew, Cigaryno Maniphest Tasks: T15623 Differential Revision: https://we.phorge.it/D25417 --- .../diffusion/controller/DiffusionBlameController.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/applications/diffusion/controller/DiffusionBlameController.php b/src/applications/diffusion/controller/DiffusionBlameController.php index 5de464b335..34078a7b7a 100644 --- a/src/applications/diffusion/controller/DiffusionBlameController.php +++ b/src/applications/diffusion/controller/DiffusionBlameController.php @@ -198,6 +198,10 @@ final class DiffusionBlameController extends DiffusionController { $map[$identifier] = $data; } + if (empty($epochs)) { + $epochs[] = 0; + } + $epoch_min = min($epochs); $epoch_max = max($epochs); From 0ec3291ff4a9249c71469f2db09c0a860770e32c Mon Sep 17 00:00:00 2001 From: bob Date: Mon, 28 Aug 2023 10:38:53 +0200 Subject: [PATCH 30/93] Fix answer background color when using Dark Mode in Ponder Summary: This CSS fix replaces the hard coded white background value by the page.content CSS variable. | Before | After | |---------|---------| |{F332921}|{F332922}| Test Plan: - Flush all Phorge caches - Sign in - Go to question with at least one answer. - Check that the answer block background color is consistent with the theme. - Do these steps for each user interface theme in order to check against regression. Reviewers: O1 Blessed Committers, valerio.bozzolan Reviewed By: O1 Blessed Committers, valerio.bozzolan Subscribers: tobiaswiese, valerio.bozzolan, Matthew, Cigaryno Differential Revision: https://we.phorge.it/D25393 --- webroot/rsrc/css/application/ponder/ponder-view.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webroot/rsrc/css/application/ponder/ponder-view.css b/webroot/rsrc/css/application/ponder/ponder-view.css index 567d7ae99b..675bc205b7 100644 --- a/webroot/rsrc/css/application/ponder/ponder-view.css +++ b/webroot/rsrc/css/application/ponder/ponder-view.css @@ -77,7 +77,7 @@ } .ponder-answer-view .ponder-answer-content { - background-color: #fff; + background-color: {$page.content}; padding: 16px 16px 0 16px; } From 4c314a733c1da104e4e30c72c7ce74766a382f5d Mon Sep 17 00:00:00 2001 From: Nicolas Aragone Date: Tue, 29 Aug 2023 18:49:23 -0300 Subject: [PATCH 31/93] Clarifying the operating system choices. Test Plan: looked at words, words looked good Reviewers: O1 Blessed Committers, chris Reviewed By: O1 Blessed Committers, chris Subscribers: tobiaswiese, valerio.bozzolan, Matthew, Cigaryno Tags: #documentation Differential Revision: https://we.phorge.it/D25427 --- src/docs/user/installation_guide.diviner | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/docs/user/installation_guide.diviner b/src/docs/user/installation_guide.diviner index ec7aa186d2..135c94adc0 100644 --- a/src/docs/user/installation_guide.diviner +++ b/src/docs/user/installation_guide.diviner @@ -54,12 +54,12 @@ Phorge from any operating system with a web browser. However, the server software does not run on Windows. It does run on most other operating systems, so choose one of these instead: - - **Linux**: Most installs use Linux. - - **Mac OS X**: Mac OS X is an acceptable flavor of Linux. - - **FreeBSD**: While FreeBSD is certainly not a flavor of Linux, it is a fine + - **GNU/Linux**: Most installs use Linux. + - **Mac OS X**: Mac OS X is an acceptable non-flavor of Linux. + - **BSD**: While BSD is certainly not a flavor of Linux, it is a fine operating system possessed of many desirable qualities, and Phorge will - install and run properly on FreeBSD. - - **Solaris, etc.**: Other systems which look like Linux and quack like Linux + install and run properly on BSD. + - **Solaris, etc.**: Other systems which look like *nix and quack like *nix will generally work fine, although we may suffer a reduced ability to support and resolve issues on unusual operating systems. From aeab4efe17cfba0dcb2f2b1b487c7175d1d428b8 Mon Sep 17 00:00:00 2001 From: Aviv Eyal Date: Wed, 30 Aug 2023 11:14:14 -0700 Subject: [PATCH 32/93] Generate Diviner book for Javelin Summary: And also fix a bug in the generator script. Test Plan: Run `bin/diviner generate`, wait till the cows come home, see 3 pages about Javelin in the Diviner app. Reviewers: O1 Blessed Committers, chris Reviewed By: O1 Blessed Committers, chris Subscribers: tobiaswiese, valerio.bozzolan, Matthew, Cigaryno Differential Revision: https://we.phorge.it/D25429 --- .gitignore | 1 + .../diviner/workflow/DivinerGenerateWorkflow.php | 3 +-- webroot/rsrc/externals/javelin/docs/javelin.book | 16 ++++++++++++++++ 3 files changed, 18 insertions(+), 2 deletions(-) create mode 100644 webroot/rsrc/externals/javelin/docs/javelin.book diff --git a/.gitignore b/.gitignore index d9f44b6bab..4e3a12e5e9 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,7 @@ # Diviner /docs/ /.divinercache/ +/webroot/rsrc/externals/javelin/docs/.divinercache/ /src/.cache/ # libphutil diff --git a/src/applications/diviner/workflow/DivinerGenerateWorkflow.php b/src/applications/diviner/workflow/DivinerGenerateWorkflow.php index 866e8b9ee6..0cde772fc3 100644 --- a/src/applications/diviner/workflow/DivinerGenerateWorkflow.php +++ b/src/applications/diviner/workflow/DivinerGenerateWorkflow.php @@ -348,7 +348,7 @@ final class DivinerGenerateWorkflow extends DivinerWorkflow { $atomizers[$atomizer][] = $file; } - $root = dirname(phutil_get_library_root('phabricator')); + $root = dirname(phutil_get_library_root('phorge')); $config_root = $this->getConfig('root'); $bar = id(new PhutilConsoleProgressBar()) @@ -363,7 +363,6 @@ final class DivinerGenerateWorkflow extends DivinerWorkflow { $this->getBookConfigPath(), $class, $chunk); - $future->setCWD($config_root); $futures[] = $future; diff --git a/webroot/rsrc/externals/javelin/docs/javelin.book b/webroot/rsrc/externals/javelin/docs/javelin.book new file mode 100644 index 0000000000..7c2a0c2274 --- /dev/null +++ b/webroot/rsrc/externals/javelin/docs/javelin.book @@ -0,0 +1,16 @@ +{ + "name" : "javelin", + "title" : "Javelin Documentation", + "short" : "Javelin Docs", + "preface" : "Documentation for developers using Javelin.", + "uri.source": + "https://we.phorge.it/diffusion/P/browse/master/%f$%l", + "rules": { + "(\\.diviner$)": "DivinerArticleAtomizer" + }, + "groups": { + "concepts": { + "name": "Concepts" + } + } +} From 94c0774d80557925480c638a5b917b137ede2269 Mon Sep 17 00:00:00 2001 From: Aviv Eyal Date: Thu, 31 Aug 2023 08:17:01 -0700 Subject: [PATCH 33/93] log deprecation events in Dark Console Summary: `PhutilErrorHandler` already defines "DEPRECATED" error class, but it's not used. I plan to use it to report deprecation warnings. With this change, they will be shown in the Dark Console and in the error logs Ref T15554 This change on its own won't do anything, but is safe to land first. Test Plan: With D25387, pages that have deprecation warnings are now shown, and the deprecation message is available in the dark console (and in log). Reviewers: O1 Blessed Committers, valerio.bozzolan Reviewed By: O1 Blessed Committers, valerio.bozzolan Subscribers: speck, tobiaswiese, valerio.bozzolan, Matthew, Cigaryno Maniphest Tasks: T15554 Differential Revision: https://we.phorge.it/D25386 --- .../console/plugin/errorlog/DarkConsoleErrorLogPluginAPI.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/applications/console/plugin/errorlog/DarkConsoleErrorLogPluginAPI.php b/src/applications/console/plugin/errorlog/DarkConsoleErrorLogPluginAPI.php index bc276da0da..fb092ec763 100644 --- a/src/applications/console/plugin/errorlog/DarkConsoleErrorLogPluginAPI.php +++ b/src/applications/console/plugin/errorlog/DarkConsoleErrorLogPluginAPI.php @@ -44,6 +44,7 @@ final class DarkConsoleErrorLogPluginAPI extends Phobject { 'trace' => $metadata['trace'], ); break; + case PhutilErrorHandler::DEPRECATED: case PhutilErrorHandler::ERROR: // $value is a simple string self::$errors[] = array( From 69c64c1e83e23f11a594686d0abb3f1a74c8d4b1 Mon Sep 17 00:00:00 2001 From: Aviv Eyal Date: Thu, 31 Aug 2023 10:55:13 -0700 Subject: [PATCH 34/93] Teach Commit View about Encoding Summary: If the user specifies a text encoding via the "View Options" dropdown, respect this choice. Ref Q68. Test Plan: Play with the Encoding button in the view Reviewers: O1 Blessed Committers, valerio.bozzolan Reviewed By: O1 Blessed Committers, valerio.bozzolan Subscribers: tinloaf, speck, tobiaswiese, valerio.bozzolan, Matthew, Cigaryno Differential Revision: https://we.phorge.it/D25360 --- .../conduit/DiffusionDiffQueryConduitAPIMethod.php | 9 ++++++--- .../diffusion/controller/DiffusionDiffController.php | 1 + 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/applications/diffusion/conduit/DiffusionDiffQueryConduitAPIMethod.php b/src/applications/diffusion/conduit/DiffusionDiffQueryConduitAPIMethod.php index 694d4bc012..397ccefa86 100644 --- a/src/applications/diffusion/conduit/DiffusionDiffQueryConduitAPIMethod.php +++ b/src/applications/diffusion/conduit/DiffusionDiffQueryConduitAPIMethod.php @@ -23,6 +23,7 @@ final class DiffusionDiffQueryConduitAPIMethod return array( 'path' => 'required string', 'commit' => 'optional string', + 'encoding' => 'optional string', ); } @@ -212,18 +213,20 @@ final class DiffusionDiffQueryConduitAPIMethod return $this->getEmptyResult(); } - $parser = $this->getDefaultParser(); + $parser = $this->getDefaultParser($request); $changes = $parser->parseDiff($raw_diff); return $changes; } - private function getDefaultParser() { + private function getDefaultParser(ConduitAPIRequest $request) { $drequest = $this->getDiffusionRequest(); $repository = $drequest->getRepository(); $parser = new ArcanistDiffParser(); - $try_encoding = $repository->getDetail('encoding'); + $try_encoding = coalesce( + $request->getValue('encoding'), + $repository->getDetail('encoding')); if ($try_encoding) { $parser->setTryEncoding($try_encoding); } diff --git a/src/applications/diffusion/controller/DiffusionDiffController.php b/src/applications/diffusion/controller/DiffusionDiffController.php index 69a473dc91..a844dc23d2 100644 --- a/src/applications/diffusion/controller/DiffusionDiffController.php +++ b/src/applications/diffusion/controller/DiffusionDiffController.php @@ -48,6 +48,7 @@ final class DiffusionDiffController extends DiffusionController { array( 'commit' => $drequest->getCommit(), 'path' => $drequest->getPath(), + 'encoding' => $request->getStr('encoding'), )); $drequest->updateSymbolicCommit($data['effectiveCommit']); $raw_changes = ArcanistDiffChange::newFromConduit($data['changes']); From 68c687affdca245bf9ec1bf63575c2631e402e09 Mon Sep 17 00:00:00 2001 From: Andre Klapper Date: Sat, 2 Sep 2023 11:12:11 +0200 Subject: [PATCH 35/93] Fix call to undefined method PhutilJSON::encodeAsObject() Summary: Replace call to undefined method `PhutilJSON::encodeAsObject()` with existing `PhutilJSON::encodeFormatted()` ``` EXCEPTION: (Error) Call to undefined method PhutilJSON::encodeAsObject() at [/src/applications/transactions/xaction/PhabricatorEditEngineDefaultTransaction.php:68] ``` Closes T15603 Test Plan: Grep and read the code in https://we.phorge.it/source/arcanist/browse/master/src/parser/PhutilJSON.php Reviewers: O1 Blessed Committers, valerio.bozzolan Reviewed By: O1 Blessed Committers, valerio.bozzolan Subscribers: tobiaswiese, valerio.bozzolan, Matthew, Cigaryno Maniphest Tasks: T15603 Differential Revision: https://we.phorge.it/D25391 --- .../xaction/PhabricatorEditEngineDefaultTransaction.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/applications/transactions/xaction/PhabricatorEditEngineDefaultTransaction.php b/src/applications/transactions/xaction/PhabricatorEditEngineDefaultTransaction.php index 7b980cdb1a..38011058b6 100644 --- a/src/applications/transactions/xaction/PhabricatorEditEngineDefaultTransaction.php +++ b/src/applications/transactions/xaction/PhabricatorEditEngineDefaultTransaction.php @@ -65,7 +65,7 @@ final class PhabricatorEditEngineDefaultTransaction return id(new PhutilJSON())->encodeAsList($default_value); } - return id(new PhutilJSON())->encodeAsObject($default_value); + return id(new PhutilJSON())->encodeFormatted($default_value); } } From cef12d8dc202decc7f4088cb3402f73d74c452f3 Mon Sep 17 00:00:00 2001 From: Andre Klapper Date: Sat, 2 Sep 2023 11:15:14 +0200 Subject: [PATCH 36/93] Fix PHP 8.1 "strlen(null)" exceptions editing a form when custom field of type Date exists Summary: `strlen()` was used in Phabricator to check if a generic value is a non-empty string. This behavior is deprecated since PHP 8.1. Phorge adopts `phutil_nonempty_scalar()` as a replacement when both string and integers could be passed as a value like here. Note: this may highlight other absurd input values that might be worth correcting instead of just ignoring. If phutil_nonempty_scalar() throws an exception in your instance, report it to Phorge to evaluate and fix that specific corner case. Also fix similar warning for `ctype_digit(): Argument of type null will be interpreted as string in the future` by checking for `null` first. ``` EXCEPTION: (RuntimeException) strlen(): Passing null to parameter #1 ($string) of type string is deprecated at [/src/error/PhutilErrorHandler.php:261] arcanist(head=customOAuthUrlencodeNull, ref.master=788098096e11, ref.customOAuthUrlencodeNull=4f0f2043b7e9), phorge(head=master, ref.master=bcfcd9acfc12) #0 <#2> PhutilErrorHandler::handleError(integer, string, string, integer) called at [/src/infrastructure/customfield/standard/PhabricatorStandardCustomFieldDate.php:27] ``` ``` EXCEPTION: (RuntimeException) strlen(): Passing null to parameter #1 ($string) of type string is deprecated at [/src/error/PhutilErrorHandler.php:261] arcanist(head=customOAuthUrlencodeNull, ref.master=788098096e11, ref.customOAuthUrlencodeNull=4f0f2043b7e9), phorge(head=customFieldDate, ref.master=bcfcd9acfc12, ref.customFieldDate=bcfcd9acfc12) #0 <#2> PhutilErrorHandler::handleError(integer, string, string, integer) called at [/src/infrastructure/customfield/standard/PhabricatorStandardCustomFieldDate.php:35] ``` ``` EXCEPTION: (RuntimeException) ctype_digit(): Argument of type null will be interpreted as string in the future at [/src/error/PhutilErrorHandler.php:261] arcanist(head=customOAuthUrlencodeNull, ref.master=788098096e11, ref.customOAuthUrlencodeNull=4f0f2043b7e9), phorge(head=customFieldDate, ref.master=bcfcd9acfc12, ref.customFieldDate=bcfcd9acfc12) #0 <#2> PhutilErrorHandler::handleError(integer, string, string, integer) called at [/src/error/PhutilErrorHandler.php:261] #1 <#2> ctype_digit(NULL) called at [/src/infrastructure/customfield/standard/PhabricatorStandardCustomFieldDate.php:77] ``` Closes T15601 Test Plan: After applying these three changes and creating a custom field with `"type": "date"` under `/config/edit/maniphest.custom-field-definitions/`, the website `/transactions/editengine/maniphest.task/view/5/` renders correctly in the browser, showing "This is a preview of the current form configuration." Reviewers: O1 Blessed Committers, valerio.bozzolan Reviewed By: O1 Blessed Committers, valerio.bozzolan Subscribers: tobiaswiese, valerio.bozzolan, Matthew, Cigaryno Maniphest Tasks: T15601 Differential Revision: https://we.phorge.it/D25389 --- .../standard/PhabricatorStandardCustomFieldDate.php | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/infrastructure/customfield/standard/PhabricatorStandardCustomFieldDate.php b/src/infrastructure/customfield/standard/PhabricatorStandardCustomFieldDate.php index 4aba7543e7..eaaa301160 100644 --- a/src/infrastructure/customfield/standard/PhabricatorStandardCustomFieldDate.php +++ b/src/infrastructure/customfield/standard/PhabricatorStandardCustomFieldDate.php @@ -24,7 +24,7 @@ final class PhabricatorStandardCustomFieldDate public function getValueForStorage() { $value = $this->getFieldValue(); - if (strlen($value)) { + if (phutil_nonempty_scalar($value)) { return (int)$value; } else { return null; @@ -32,7 +32,7 @@ final class PhabricatorStandardCustomFieldDate } public function setValueFromStorage($value) { - if (strlen($value)) { + if (phutil_nonempty_scalar($value)) { $value = (int)$value; } else { $value = null; @@ -74,7 +74,8 @@ final class PhabricatorStandardCustomFieldDate // specify as a string. Parse the string into an epoch. $value = $this->getFieldValue(); - if (!ctype_digit($value)) { + if ($value !== null && gettype($value) !== 'integer' && + !ctype_digit($value)) { $value = PhabricatorTime::parseLocalTime($value, $this->getViewer()); } From dc10a7e69ea33fd4b589f0d9e8c9921bc6f94765 Mon Sep 17 00:00:00 2001 From: Benjamin Kausch Date: Sat, 2 Sep 2023 18:52:13 +0200 Subject: [PATCH 37/93] Implement ferret engine in typeahead datasource query for repos Summary: This broadens the typeahead datasource search for repos. Before this patch a repository named "Alligator Simulator" would not be found with the search string "simu...". This is patched with the ferret engine search and indexing features. See T15583 Test Plan: Create repositories with titles with 2 or more words. Search for these repos with the global typeahead search. The search term should begin with the second/third/n-th word of the repo title. Reviewers: O1 Blessed Committers, avivey Reviewed By: O1 Blessed Committers, avivey Subscribers: avivey, tobiaswiese, valerio.bozzolan, Matthew, Cigaryno Maniphest Tasks: T15583 Differential Revision: https://we.phorge.it/D25430 --- .../20230902.repository.01.rebuild-index.php | 6 +++++ .../DiffusionRepositoryDatasource.php | 15 ++++++++----- .../query/PhabricatorRepositoryQuery.php | 22 ------------------- .../PhabricatorRepositoryFulltextEngine.php | 15 +++++++++++-- 4 files changed, 28 insertions(+), 30 deletions(-) create mode 100644 resources/sql/autopatches/20230902.repository.01.rebuild-index.php diff --git a/resources/sql/autopatches/20230902.repository.01.rebuild-index.php b/resources/sql/autopatches/20230902.repository.01.rebuild-index.php new file mode 100644 index 0000000000..aba27ce78c --- /dev/null +++ b/resources/sql/autopatches/20230902.repository.01.rebuild-index.php @@ -0,0 +1,6 @@ +getViewer(); - $raw_query = $this->getRawQuery(); - $query = id(new PhabricatorRepositoryQuery()) - ->setOrder('name') - ->withDatasourceQuery($raw_query); - $repos = $this->executeQuery($query); + ->setViewer($this->getViewer()); + + $this->applyFerretConstraints( + $query, + id(new PhabricatorRepository())->newFerretEngine(), + 'title', + $this->getRawQuery()); + + $repos = $query->execute(); $type_icon = id(new PhabricatorRepositoryRepositoryPHIDType()) ->getTypeIcon(); diff --git a/src/applications/repository/query/PhabricatorRepositoryQuery.php b/src/applications/repository/query/PhabricatorRepositoryQuery.php index 17a46f7b62..8dead39758 100644 --- a/src/applications/repository/query/PhabricatorRepositoryQuery.php +++ b/src/applications/repository/query/PhabricatorRepositoryQuery.php @@ -9,7 +9,6 @@ final class PhabricatorRepositoryQuery private $types; private $uuids; private $uris; - private $datasourceQuery; private $slugs; private $almanacServicePHIDs; @@ -124,11 +123,6 @@ final class PhabricatorRepositoryQuery return $this; } - public function withDatasourceQuery($query) { - $this->datasourceQuery = $query; - return $this; - } - public function withSlugs(array $slugs) { $this->slugs = $slugs; return $this; @@ -637,22 +631,6 @@ final class PhabricatorRepositoryQuery $this->uuids); } - if (phutil_nonempty_string($this->datasourceQuery)) { - // This handles having "rP" match callsigns starting with "P...". - $query = trim($this->datasourceQuery); - if (preg_match('/^r/', $query)) { - $callsign = substr($query, 1); - } else { - $callsign = $query; - } - $where[] = qsprintf( - $conn, - 'r.name LIKE %> OR r.callsign LIKE %> OR r.repositorySlug LIKE %>', - $query, - $callsign, - $query); - } - if ($this->slugs !== null) { $where[] = qsprintf( $conn, diff --git a/src/applications/repository/search/PhabricatorRepositoryFulltextEngine.php b/src/applications/repository/search/PhabricatorRepositoryFulltextEngine.php index f666af552f..838692c351 100644 --- a/src/applications/repository/search/PhabricatorRepositoryFulltextEngine.php +++ b/src/applications/repository/search/PhabricatorRepositoryFulltextEngine.php @@ -7,10 +7,21 @@ final class PhabricatorRepositoryFulltextEngine PhabricatorSearchAbstractDocument $document, $object) { $repo = $object; - $document->setDocumentTitle($repo->getName()); + + $title_fields = array( + $repo->getName(), + $repo->getRepositorySlug(), + ); + $callsign = $repo->getCallsign(); + if ($callsign) { + $title_fields[] = $callsign; + $title_fields[] = 'r'.$callsign; + } + + $document->setDocumentTitle(implode("\n", $title_fields)); $document->addField( PhabricatorSearchDocumentFieldType::FIELD_BODY, - $repo->getRepositorySlug()."\n".$repo->getDetail('description')); + $repo->getDetail('description')); $document->setDocumentCreated($repo->getDateCreated()); $document->setDocumentModified($repo->getDateModified()); From 7868ab3754fad13714640451d664d5bc71b7a02f Mon Sep 17 00:00:00 2001 From: Andre Klapper Date: Sat, 19 Aug 2023 20:18:45 +0200 Subject: [PATCH 38/93] Make InterpreterBlockRule regex only match on valid interpreter names Summary: With this patch, the underlying exception described in T15372#8537 still remains. However, with this patch, the bug is more contained as it is not triggered when not calling an interpreter (`cowsay`, `figlet`), so Phorge does not crash rendering `noValidInterpreter {{{foo}}} bar` lines but renders them as is (for whatever reasons such lines may exist). See T15372 Test Plan: Enter strings into a comment: * `invalid {{{saysay}}} foo` now renders as plain text instead of crashing * `invalid (invalid) {{{saysay}}} foo` now renders as plain text instead of crashing * `cowsay (invalid) {{{saysay}}} foo` will still crash as before Reviewers: O1 Blessed Committers, valerio.bozzolan Reviewed By: O1 Blessed Committers, valerio.bozzolan Subscribers: tobiaswiese, valerio.bozzolan, Matthew, Cigaryno Differential Revision: https://we.phorge.it/D25415 --- .../PhutilRemarkupInterpreterBlockRule.php | 30 ++++++++++++++++--- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/src/infrastructure/markup/blockrule/PhutilRemarkupInterpreterBlockRule.php b/src/infrastructure/markup/blockrule/PhutilRemarkupInterpreterBlockRule.php index a54e6b8b13..5585ddf541 100644 --- a/src/infrastructure/markup/blockrule/PhutilRemarkupInterpreterBlockRule.php +++ b/src/infrastructure/markup/blockrule/PhutilRemarkupInterpreterBlockRule.php @@ -2,13 +2,35 @@ final class PhutilRemarkupInterpreterBlockRule extends PhutilRemarkupBlockRule { - const START_BLOCK_PATTERN = '/^([\w]+)\s*(?:\(([^)]+)\)\s*)?{{{/'; + /** + * Second part of the regex to find stuff like: + * interpreterName {{{ stuff }}} + * interpreterName (options) {{{ stuff }}} + * You have found the kernel of cowsay and figlet. + */ const END_BLOCK_PATTERN = '/}}}\s*$/'; + /** + * Constructs the first part of the regex to find stuff like: + * interpreterName {{{ stuff }}} + * interpreterName (options) {{{ stuff }}} + * The exact regex is constructed from the available interpreters. + * @return string First part of interpreters regex + */ + private function getStartBlockPattern() { + $interpreters = id(new PhutilClassMapQuery()) + ->setAncestorClass('PhutilRemarkupBlockInterpreter') + ->execute(); + $interpreters_regex = mpull($interpreters, 'getInterpreterName'); + $interpreters_regex = array_map('preg_quote', $interpreters_regex); + $interpreters_regex = implode('|', $interpreters_regex); + return "/^($interpreters_regex)\s*(?:\(([^)]+)\)\s*)?{{{/"; + } + public function getMatchingLineCount(array $lines, $cursor) { $num_lines = 0; - if (preg_match(self::START_BLOCK_PATTERN, $lines[$cursor])) { + if (preg_match(self::getStartBlockPattern(), $lines[$cursor])) { $num_lines++; while (isset($lines[$cursor])) { @@ -33,7 +55,7 @@ final class PhutilRemarkupInterpreterBlockRule extends PhutilRemarkupBlockRule { } $matches = null; - preg_match(self::START_BLOCK_PATTERN, head($lines), $matches); + preg_match(self::getStartBlockPattern(), head($lines), $matches); $argv = array(); if (isset($matches[2])) { @@ -49,7 +71,7 @@ final class PhutilRemarkupInterpreterBlockRule extends PhutilRemarkupBlockRule { } $lines[$first_key] = preg_replace( - self::START_BLOCK_PATTERN, + self::getStartBlockPattern(), '', $lines[$first_key]); $lines[$last_key] = preg_replace( From 1720209f16c3962ac108c99b9a3dbc00f72a42da Mon Sep 17 00:00:00 2001 From: sten Date: Sat, 29 Jul 2023 20:42:49 +0100 Subject: [PATCH 39/93] Various PHP 8.1 strlen(null) fixes for Dashboard Panels Summary: In the dashboard application (https://my.phorge.site/dashboard/), when creating panels, adding panels to tab panels, and viewing query panels, we get a variety of strlen(null) errors under PHP 8.1. This fixes all the ones seen. Fixes T15574 Test Plan: See T15574 Reviewers: O1 Blessed Committers, avivey Reviewed By: O1 Blessed Committers, avivey Subscribers: avivey, speck, tobiaswiese, valerio.bozzolan, Matthew, Cigaryno Maniphest Tasks: T15574 Differential Revision: https://we.phorge.it/D25367 --- .../dashboard/PhabricatorDashboardAdjustController.php | 2 +- .../panel/PhabricatorDashboardPanelTabsController.php | 4 ++-- .../engine/PhabricatorDashboardPanelRenderingEngine.php | 1 + .../dashboard/paneltype/PhabricatorDashboardTabsPanelType.php | 2 +- .../PhabricatorFerretSearchEngineExtension.php | 2 +- 5 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/applications/dashboard/controller/dashboard/PhabricatorDashboardAdjustController.php b/src/applications/dashboard/controller/dashboard/PhabricatorDashboardAdjustController.php index fc04b94603..4f3937e3ae 100644 --- a/src/applications/dashboard/controller/dashboard/PhabricatorDashboardAdjustController.php +++ b/src/applications/dashboard/controller/dashboard/PhabricatorDashboardAdjustController.php @@ -32,7 +32,7 @@ final class PhabricatorDashboardAdjustController $panel_ref = null; $panel_key = $request->getStr('panelKey'); - if (strlen($panel_key)) { + if ($panel_key !== null && strlen($panel_key)) { $panel_ref = $ref_list->getPanelRef($panel_key); if (!$panel_ref) { return new Aphront404Response(); diff --git a/src/applications/dashboard/controller/panel/PhabricatorDashboardPanelTabsController.php b/src/applications/dashboard/controller/panel/PhabricatorDashboardPanelTabsController.php index 193e4580d6..7ea0345ceb 100644 --- a/src/applications/dashboard/controller/panel/PhabricatorDashboardPanelTabsController.php +++ b/src/applications/dashboard/controller/panel/PhabricatorDashboardPanelTabsController.php @@ -41,12 +41,12 @@ final class PhabricatorDashboardPanelTabsController $op = $request->getURIData('op'); $after = $request->getStr('after'); - if (!strlen($after)) { + if ($after === '') { $after = null; } $target = $request->getStr('target'); - if (!strlen($target)) { + if ($target === '') { $target = null; } diff --git a/src/applications/dashboard/engine/PhabricatorDashboardPanelRenderingEngine.php b/src/applications/dashboard/engine/PhabricatorDashboardPanelRenderingEngine.php index cce6ee768f..3b9c3ad192 100644 --- a/src/applications/dashboard/engine/PhabricatorDashboardPanelRenderingEngine.php +++ b/src/applications/dashboard/engine/PhabricatorDashboardPanelRenderingEngine.php @@ -155,6 +155,7 @@ final class PhabricatorDashboardPanelRenderingEngine extends Phobject { return $this->renderNormalPanel(); } catch (Exception $ex) { + phlog($ex); return $this->renderErrorPanel( $panel->getName(), pht( diff --git a/src/applications/dashboard/paneltype/PhabricatorDashboardTabsPanelType.php b/src/applications/dashboard/paneltype/PhabricatorDashboardTabsPanelType.php index 9bc84d820e..3cf73b539e 100644 --- a/src/applications/dashboard/paneltype/PhabricatorDashboardTabsPanelType.php +++ b/src/applications/dashboard/paneltype/PhabricatorDashboardTabsPanelType.php @@ -100,7 +100,7 @@ final class PhabricatorDashboardTabsPanelType $panel_id = idx($tab_spec, 'panelID'); $subpanel = idx($panels, $panel_id); - $name = idx($tab_spec, 'name'); + $name = coalesce(idx($tab_spec, 'name'), ''); if (!strlen($name)) { if ($subpanel) { $name = $subpanel->getName(); diff --git a/src/applications/search/engineextension/PhabricatorFerretSearchEngineExtension.php b/src/applications/search/engineextension/PhabricatorFerretSearchEngineExtension.php index 55b7c2225a..2544f8b7da 100644 --- a/src/applications/search/engineextension/PhabricatorFerretSearchEngineExtension.php +++ b/src/applications/search/engineextension/PhabricatorFerretSearchEngineExtension.php @@ -27,7 +27,7 @@ final class PhabricatorFerretSearchEngineExtension PhabricatorSavedQuery $saved, array $map) { - if (!strlen($map['query'])) { + if (!(isset($map['query']) && strlen($map['query']))) { return; } From f7d9d95b79f781eea88f37058aa0ffa5622995ff Mon Sep 17 00:00:00 2001 From: sten Date: Tue, 5 Sep 2023 17:02:58 +0100 Subject: [PATCH 40/93] Fix Diviner strlen(null) error when clicking on a link Summary: Fix issue whereby clicking on a link in Diviner (eg https://my.phorge.site/diviner/find/?name=Differential_User_Guide&type=article&jump=1) results in a strlen(null) error under PHP 8.1 Fixes T15635 Test Plan: * Go into the Diviner differential page /book/phorge/article/differential/ * Click on the link to Differential User Guide: Inline Comments Reviewers: O1 Blessed Committers, valerio.bozzolan Reviewed By: O1 Blessed Committers, valerio.bozzolan Subscribers: tobiaswiese, valerio.bozzolan, Matthew, Cigaryno Maniphest Tasks: T15635 Differential Revision: https://we.phorge.it/D25433 --- src/applications/diviner/controller/DivinerFindController.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/applications/diviner/controller/DivinerFindController.php b/src/applications/diviner/controller/DivinerFindController.php index 1bedd65b06..2e3b121706 100644 --- a/src/applications/diviner/controller/DivinerFindController.php +++ b/src/applications/diviner/controller/DivinerFindController.php @@ -32,7 +32,7 @@ final class DivinerFindController extends DivinerController { } $context = $request->getStr('context'); - if (strlen($context)) { + if (phutil_nonempty_string($context)) { $query->withContexts(array($context)); } From a65061ddc33da26a203d3a7b73ff0e491a5b9788 Mon Sep 17 00:00:00 2001 From: Andre Klapper Date: Sat, 9 Sep 2023 20:54:44 +0200 Subject: [PATCH 41/93] Fix PHP 8.1 "strlen(null)" exception rendering Task with empty custom date field Summary: `strlen()` was used in Phabricator to check if a generic value is a non-empty string. This behavior is deprecated since PHP 8.1. Phorge adopts `phutil_nonempty_string()` as a replacement. Note: this may highlight other absurd input values that might be worth correcting instead of just ignoring. If phutil_nonempty_string() throws an exception in your instance, report it to Phorge to evaluate and fix that specific corner case. ``` EXCEPTION: (RuntimeException) strlen(): Passing null to parameter #1 ($string) of type string is deprecated at [/src/error/PhutilErrorHandler.php:261] arcanist(head=customOAuthUrlencodeNull, ref.master=df6c315ace5f, ref.customOAuthUrlencodeNull=c69b9749027f), phorge(head=master, ref.master=7868ab3754fa) #0 <#2> PhutilErrorHandler::handleError(integer, string, string, integer) called at [/src/infrastructure/customfield/standard/PhabricatorStandardCustomFieldDate.php:14] ``` Closes T15632 Test Plan: Have a custom field with type=date defined in maniphest.custom-field-definitions and edit an existing Task changing something else, keeping that field as empty. Reviewers: O1 Blessed Committers, Sten, valerio.bozzolan Reviewed By: O1 Blessed Committers, Sten, valerio.bozzolan Subscribers: tobiaswiese, valerio.bozzolan, Matthew, Cigaryno Maniphest Tasks: T15632 Differential Revision: https://we.phorge.it/D25431 --- .../customfield/standard/PhabricatorStandardCustomFieldDate.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/infrastructure/customfield/standard/PhabricatorStandardCustomFieldDate.php b/src/infrastructure/customfield/standard/PhabricatorStandardCustomFieldDate.php index eaaa301160..ca56816b42 100644 --- a/src/infrastructure/customfield/standard/PhabricatorStandardCustomFieldDate.php +++ b/src/infrastructure/customfield/standard/PhabricatorStandardCustomFieldDate.php @@ -11,7 +11,7 @@ final class PhabricatorStandardCustomFieldDate $indexes = array(); $value = $this->getFieldValue(); - if (strlen($value)) { + if (phutil_nonempty_scalar($value)) { $indexes[] = $this->newNumericIndex((int)$value); } From a0fb344b94883d54fb958aa78f9a8c715ffae185 Mon Sep 17 00:00:00 2001 From: sten Date: Tue, 5 Sep 2023 15:14:06 +0100 Subject: [PATCH 42/93] Fix PHP 8.1 auth view strlen(null) error Summary: Trying to view a Jira auth provider from https://my.phorge.site/auth/ results in strlen(): Passing null to parameter #1 ($string) of type string is deprecated This change fixes it Fixes T15634 Test Plan: Go to https://my.phorge.site/auth/ and have a Jira already setup. Click on Jira auth provider Confirm the page is displayed and no error is generated. Reviewers: O1 Blessed Committers, valerio.bozzolan Reviewed By: O1 Blessed Committers, valerio.bozzolan Subscribers: tobiaswiese, valerio.bozzolan, Matthew, Cigaryno Maniphest Tasks: T15634 Differential Revision: https://we.phorge.it/D25432 --- .../auth/storage/PhabricatorAuthProviderConfigTransaction.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/applications/auth/storage/PhabricatorAuthProviderConfigTransaction.php b/src/applications/auth/storage/PhabricatorAuthProviderConfigTransaction.php index f60ba8c734..d7f974cb15 100644 --- a/src/applications/auth/storage/PhabricatorAuthProviderConfigTransaction.php +++ b/src/applications/auth/storage/PhabricatorAuthProviderConfigTransaction.php @@ -150,7 +150,7 @@ final class PhabricatorAuthProviderConfigTransaction $provider = $this->getProvider(); if ($provider) { $title = $provider->renderConfigPropertyTransactionTitle($this); - if (strlen($title)) { + if (phutil_nonempty_string($title)) { return $title; } } From 91faf16cace9308440087d64f17c068e04313c50 Mon Sep 17 00:00:00 2001 From: sten Date: Wed, 6 Sep 2023 07:55:56 +0100 Subject: [PATCH 43/93] Add documentation for cowsay Summary: Cowsay is great, but what if you want to talk like a koala? This diff adds diviner documentation on how to use the additional templates in externals/cowsay/cows/ Test Plan: bin/diviner generate https://my.phorge.site/book/phorge/article/differential_cowsay/ Reviewers: O1 Blessed Committers, valerio.bozzolan Reviewed By: O1 Blessed Committers, valerio.bozzolan Subscribers: tobiaswiese, valerio.bozzolan, Matthew, Cigaryno Differential Revision: https://we.phorge.it/D25434 --- src/docs/user/userguide/differential.diviner | 1 + .../user/userguide/differential_faq.diviner | 9 ++- src/docs/user/userguide/remarkup.diviner | 4 ++ .../user/userguide/remarkup_cowsay.diviner | 61 +++++++++++++++++++ 4 files changed, 73 insertions(+), 2 deletions(-) create mode 100644 src/docs/user/userguide/remarkup_cowsay.diviner diff --git a/src/docs/user/userguide/differential.diviner b/src/docs/user/userguide/differential.diviner index d48ff4ceff..fad92dfa4e 100644 --- a/src/docs/user/userguide/differential.diviner +++ b/src/docs/user/userguide/differential.diviner @@ -66,6 +66,7 @@ Continue by: - diving into the details of inline comments in @{article:Differential User Guide: Inline Comments}; or - reading the FAQ at @{article:Differential User Guide: FAQ}; or + - learning how to use markup in comments at @{article:Remarkup Reference}; or - learning about test plans in @{article:Differential User Guide: Test Plans}; or - learning more about Herald in @{article:Herald User Guide}. diff --git a/src/docs/user/userguide/differential_faq.diviner b/src/docs/user/userguide/differential_faq.diviner index 0df1f7b1c9..979daf762a 100644 --- a/src/docs/user/userguide/differential_faq.diviner +++ b/src/docs/user/userguide/differential_faq.diviner @@ -41,8 +41,9 @@ always "request review" of an accepted revision, with a comment like: If authors are being jerks about this (making sweeping changes as soon as they get an accept), solve the problem socially by telling them to stop being jerks. -Unless you've configured additional layers of enforcement, there's nothing -stopping them from silently changing the code before pushing it, anyway. +Unless you've configured additional layers of enforcement (by +using @{article:Herald}), there's nothing stopping them from silently changing +the code before pushing it, anyway. = How can I enable syntax highlighting? = @@ -50,6 +51,10 @@ stopping them from silently changing the code before pushing it, anyway. You need to install and configure **Pygments** to highlight anything else than PHP. See the `pygments.enabled` configuration setting. += What formatting can be used in comments? = + +Phorge implements a markup language similar to other markup languages like +Markdown and Wiki markup. See @{article:Remarkup Reference}. = What do the very light green and red backgrounds mean? = diff --git a/src/docs/user/userguide/remarkup.diviner b/src/docs/user/userguide/remarkup.diviner index 4fb8fc75f8..fa0128127c 100644 --- a/src/docs/user/userguide/remarkup.diviner +++ b/src/docs/user/userguide/remarkup.diviner @@ -732,3 +732,7 @@ to the first anchor with "xyz" as a prefix of the anchor name. Remarkup editors provide a fullscreen composition mode. This can make it easier to edit large blocks of text, or improve focus by removing distractions. You can exit **Fullscreen** mode by clicking the button again or by pressing escape. + +See Also +======== +* @{article:Remarkup Reference: Cowsay} diff --git a/src/docs/user/userguide/remarkup_cowsay.diviner b/src/docs/user/userguide/remarkup_cowsay.diviner new file mode 100644 index 0000000000..696189afb6 --- /dev/null +++ b/src/docs/user/userguide/remarkup_cowsay.diviner @@ -0,0 +1,61 @@ +@title Remarkup Reference: Cowsay +@group userguide + +Overview +-------- + +Cowsay is an application by Tony Monroe which has been ported over to +Phabricator/Phorge to allow your comments to be voiced by +a cow. + +Basic Usage +----------- + +A basic example of using cowsay would be to add a comment + cowsay{{{Great work!}}} +which generates: +``` + _____________ +< Great work! > + ------------- + \ ^__^ + \ (oo)\_______ + (__)\ )\/\ + ||----w | + || || +``` + +Other Cowsay Templates +---------------------- +Other templates are available in externals/cowsay/cows/, and you can specify +one by calling cowsay with the 'cow' parameter. eg: + cowsay(cow='tux'){{{Great work!}}} +generates +``` + _____________ +< Great work! > + ------------- + \ + \ + .--. + |o_o | + |:_/ | + // \ \ + (| | ) + /'\_ _/`\ + \___)=(___/ +``` + +Other Parameters +---------------- +* think (set to 1 for thinking bubbles) +* eyes (default 'oo') +* tongue (default ' ', try 'P') + +See Also +======== +* @{article:Remarkup Reference} +* Have you tried figlet: +``` +figlet{{{figlet generates big text!}}} +``` From 903d71e67d84e04337d6dc4d9febcd71eb6f9c53 Mon Sep 17 00:00:00 2001 From: Valerio Bozzolan Date: Mon, 25 Sep 2023 08:06:09 +0200 Subject: [PATCH 44/93] Workboard: Milestone Name easily editable (instead of surfing 3 pages) Summary: After this change, a new input field "Milestone Name" appears in the "Edit" menu of a Milestone: | Before | After | |-----------|-----------| | {F314008} | {F314005} | So you can quickly change the name of your Milestones, from a Workboard. Before this change, from a Workboard, this was the way to rename a Milestone: 1. click on the Milestone name (yes, that is a link) 2. click on Manage 3. click on Edit Details 4. rename 5. Save 6. Manually visit again the Project's Workboard After this change, from a Workboard, you just need to: 1. click on Milestone > Edit 2. click on Edit Column 3. rename 4. Save Example usage: {F314015} This does not change the level of permissions needed: if you have not enough permissions to see or edit a Milestone, you cannot access this feature indeed. In short, this is just a frontend change, keeping current policies as-is. Closes T15143 Test Plan: Create a Project or use an existing editable one. Create a Milestone called "Test Milestone". You can create Milestones visiting the Project's menu {nav icon=sitemap,name=Subprojects > icon=plus,name=Create next milestone} Visit the Project's Workboard. Find the column "Test Milestone". Click the Edit button on a Milestone, and: - try to save another name: it must work - try to save an empty name: nice error message shown - try to save both the score points and the name: it must work - try to save "FOO" as Points: you still see the error message Also: - do the same for the Backlog column: it still works (name still allowed to be empty) - do the same for a "normal" Column (not the Backlog): it still work (name still __not__ allowed to be empty) Reviewers: O1 Blessed Committers, Cigaryno, 20after4, waldyrious Reviewed By: O1 Blessed Committers, Cigaryno, 20after4, waldyrious Subscribers: waldyrious, brennen, aklapper, 20after4, speck, tobiaswiese, Matthew, Cigaryno Maniphest Tasks: T15143 Differential Revision: https://we.phorge.it/D25066 --- ...PhabricatorProjectColumnEditController.php | 59 ++++++++++++++++++- 1 file changed, 56 insertions(+), 3 deletions(-) diff --git a/src/applications/project/controller/PhabricatorProjectColumnEditController.php b/src/applications/project/controller/PhabricatorProjectColumnEditController.php index 9ddb2b7d8a..bf579b274f 100644 --- a/src/applications/project/controller/PhabricatorProjectColumnEditController.php +++ b/src/applications/project/controller/PhabricatorProjectColumnEditController.php @@ -45,16 +45,32 @@ final class PhabricatorProjectColumnEditController $e_name = null; $e_limit = null; + $e_milestone_name = null; $v_limit = $column->getPointLimit(); $v_name = $column->getName(); + $proxy = $column->getProxy(); + + // Is this a normal Column? Example: when true, this is not a Milestone. + $is_column = !$proxy; + + // Is this a Milestone? Example: when true, this is not a normal Column. + $is_milestone = $proxy && $proxy->isMilestone(); + + // Milestone name, eventually coming from the proxed object. + $v_milestone_name = null; + if ($is_milestone) { + $v_milestone_name = $proxy->getName(); + } + $validation_exception = null; $view_uri = $project->getWorkboardURI(); if ($request->isFormPost()) { $v_name = $request->getStr('name'); $v_limit = $request->getStr('limit'); + $v_milestone_name = $request->getStr('milestone.name'); if ($is_new) { $column->setProjectPHID($project->getPHID()); @@ -74,14 +90,22 @@ final class PhabricatorProjectColumnEditController } $xactions = array(); + $xactions_milestone = array(); $type_name = PhabricatorProjectColumnNameTransaction::TRANSACTIONTYPE; $type_limit = PhabricatorProjectColumnLimitTransaction::TRANSACTIONTYPE; + $type_project_name = PhabricatorProjectNameTransaction::TRANSACTIONTYPE; - if (!$column->getProxy()) { + if ($is_column) { + // Transaction for Column name. $xactions[] = id(new PhabricatorProjectColumnTransaction()) ->setTransactionType($type_name) ->setNewValue($v_name); + } else if ($is_milestone) { + // Transaction for Milestone name (that internally is a Project Name). + $xactions_milestone[] = id(new PhabricatorProjectTransaction()) + ->setTransactionType($type_project_name) + ->setNewValue($v_milestone_name); } $xactions[] = id(new PhabricatorProjectColumnTransaction()) @@ -94,24 +118,53 @@ final class PhabricatorProjectColumnEditController ->setContinueOnNoEffect(true) ->setContentSourceFromRequest($request) ->applyTransactions($column, $xactions); - return id(new AphrontRedirectResponse())->setURI($view_uri); } catch (PhabricatorApplicationTransactionValidationException $ex) { + // Error messages related to the Column (like invalid Name, etc.) $e_name = $ex->getShortMessage($type_name); $e_limit = $ex->getShortMessage($type_limit); $validation_exception = $ex; } + + // Save Milestone-related stuff but only if there were no prior problems + // and only if we have changes. + if (!$validation_exception && $xactions_milestone) { + try { + $editor_milestone = id(new PhabricatorProjectTransactionEditor()) + ->setActor($viewer) + ->setContinueOnNoEffect(true) + ->setContentSourceFromRequest($request) + ->applyTransactions($proxy, $xactions_milestone); + } catch (PhabricatorApplicationTransactionValidationException $ex) { + // Error messages related to the Milestone (like invalid Name, etc.) + $e_milestone_name = $ex->getShortMessage($type_project_name); + $validation_exception = $ex; + } + } + + // Refresh the page only if there are no errors to show. + if (!$validation_exception) { + return id(new AphrontRedirectResponse())->setURI($view_uri); + } } $form = id(new AphrontFormView()) ->setUser($request->getUser()); - if (!$column->getProxy()) { + // Show the most appropriate input field for the name. + if ($is_column) { $form->appendChild( id(new AphrontFormTextControl()) ->setValue($v_name) ->setLabel(pht('Name')) ->setName('name') ->setError($e_name)); + } else if ($is_milestone) { + $form->appendChild( + id(new AphrontFormTextControl()) + ->setValue($v_milestone_name) + ->setLabel(pht('Milestone Name')) + ->setName('milestone.name') + ->setError($e_milestone_name)); } $form->appendChild( From 03afb97ff20bd5480ecfa0fa809e3b751bd973e8 Mon Sep 17 00:00:00 2001 From: Andre Klapper Date: Wed, 27 Sep 2023 18:50:08 +0200 Subject: [PATCH 45/93] Correct Transaction text when changing Diffusion URI I/O type Summary: After changing the I/O type of a Diffusion repository URI, the transaction history incorrectly shows a message which talks about changing the URI's Display type instead. Closes T15648 Test Plan: Change the I/O type of a Diffusion repo URI and look at that URIs history. Reviewers: O1 Blessed Committers, avivey Reviewed By: O1 Blessed Committers, avivey Subscribers: tobiaswiese, valerio.bozzolan, Matthew, Cigaryno Maniphest Tasks: T15648 Differential Revision: https://we.phorge.it/D25443 --- .../repository/storage/PhabricatorRepositoryURITransaction.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/applications/repository/storage/PhabricatorRepositoryURITransaction.php b/src/applications/repository/storage/PhabricatorRepositoryURITransaction.php index 241a95dad9..49d1a44943 100644 --- a/src/applications/repository/storage/PhabricatorRepositoryURITransaction.php +++ b/src/applications/repository/storage/PhabricatorRepositoryURITransaction.php @@ -57,7 +57,7 @@ final class PhabricatorRepositoryURITransaction $new_label = idx(idx($map, $new, array()), 'label', $new); return pht( - '%s changed the display type for this URI from "%s" to "%s".', + '%s changed the I/O type for this URI from "%s" to "%s".', $this->renderHandleLink($author_phid), $old_label, $new_label); From 71b273a62281204a7bcce39fea9ebc16157f3ef7 Mon Sep 17 00:00:00 2001 From: Francesco Gazzetta Date: Tue, 3 Oct 2023 13:36:06 +0200 Subject: [PATCH 46/93] Update path in startup error Summary: The error mentioned a "phabricator" directory, but according to the docs it has been migrated to "phorge". Test Plan: Move the "arcanist" directory somewhere else, run something from phorge/bin/. Reviewers: O1 Blessed Committers, valerio.bozzolan Reviewed By: O1 Blessed Committers, valerio.bozzolan Subscribers: tobiaswiese, valerio.bozzolan, Matthew, Cigaryno Differential Revision: https://we.phorge.it/D25445 --- support/startup/PhabricatorStartup.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/support/startup/PhabricatorStartup.php b/support/startup/PhabricatorStartup.php index 58031013ad..b9d659d39b 100644 --- a/support/startup/PhabricatorStartup.php +++ b/support/startup/PhabricatorStartup.php @@ -210,7 +210,7 @@ final class PhabricatorStartup { if (!$ok) { self::didFatal( 'Unable to load the "Arcanist" library. Put "arcanist/" next to '. - '"phabricator/" on disk.'); + '"phorge/" on disk.'); } // Load Phabricator itself using the absolute path, so we never end up doing From f727f17bc24a03cf1c6c82be3778e58e4fa282d7 Mon Sep 17 00:00:00 2001 From: Valerio Bozzolan Date: Tue, 10 Oct 2023 07:16:05 +0200 Subject: [PATCH 47/93] Fix regression in DiffusionDiffQueryConduitAPIMethod Summary: Fix the following error you may encounter in production: Too few arguments to function DiffusionDiffQueryConduitAPIMethod::getDefaultParser(), 0 passed in /var/www/phorge/src/applications/diffusion/conduit/DiffusionDiffQueryConduitAPIMethod.php on line 156 and exactly 1 expected It was caused by the lack of a new mandatory parameter in a method. Closes T15649 Test Plan: Check with your big eyes that a ConduitAPIRequest is passed to getDefaultParser(). Reviewers: avivey, O1 Blessed Committers, speck Reviewed By: O1 Blessed Committers, speck Subscribers: speck, tobiaswiese, Matthew, Cigaryno Maniphest Tasks: T15649 Differential Revision: https://we.phorge.it/D25444 --- .../diffusion/conduit/DiffusionDiffQueryConduitAPIMethod.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/applications/diffusion/conduit/DiffusionDiffQueryConduitAPIMethod.php b/src/applications/diffusion/conduit/DiffusionDiffQueryConduitAPIMethod.php index 397ccefa86..d97f09cc4e 100644 --- a/src/applications/diffusion/conduit/DiffusionDiffQueryConduitAPIMethod.php +++ b/src/applications/diffusion/conduit/DiffusionDiffQueryConduitAPIMethod.php @@ -153,7 +153,7 @@ final class DiffusionDiffQueryConduitAPIMethod $arcanist_changes = DiffusionPathChange::convertToArcanistChanges( $path_changes); - $parser = $this->getDefaultParser(); + $parser = $this->getDefaultParser($request); $parser->setChanges($arcanist_changes); $parser->forcePath($path->getPath()); $changes = $parser->parseDiff($raw_diff); From 94aefaa31d4c781d2553345e2994155067d9f238 Mon Sep 17 00:00:00 2001 From: "roberto.urbani" Date: Fri, 13 Oct 2023 10:46:21 +0200 Subject: [PATCH 48/93] Replacing the deprecated -moz-outline-style with outline-style Summary: Replacing the deprecated -moz-outline-style with outline-style: none. According to "Can I Use", this change is supported in whatever non-ridiculously-old browser web in the universe, like Firefox 2 and Chrome 4 and Internet Explorer 8. https://caniuse.com/outline Ref T15585 Test Plan: The outline in the tags should look as usual, that is, none. Reviewers: O1 Blessed Committers, valerio.bozzolan Reviewed By: O1 Blessed Committers, valerio.bozzolan Subscribers: tobiaswiese, valerio.bozzolan, Matthew, Cigaryno Maniphest Tasks: T15585 Differential Revision: https://we.phorge.it/D25416 --- resources/celerity/map.php | 6 +++--- webroot/rsrc/css/core/core.css | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/resources/celerity/map.php b/resources/celerity/map.php index 8f791cbeda..e40b474c14 100644 --- a/resources/celerity/map.php +++ b/resources/celerity/map.php @@ -9,7 +9,7 @@ return array( 'names' => array( 'conpherence.pkg.css' => '76ed87e3', 'conpherence.pkg.js' => '020aebcf', - 'core.pkg.css' => '1a5169fe', + 'core.pkg.css' => '3c4918b0', 'core.pkg.js' => '2eeda9e0', 'dark-console.pkg.js' => '187792c2', 'differential.pkg.css' => '2431def2', @@ -109,7 +109,7 @@ return array( 'rsrc/css/application/slowvote/slowvote.css' => '1694baed', 'rsrc/css/application/tokens/tokens.css' => 'ce5a50bd', 'rsrc/css/application/uiexample/example.css' => 'b4795059', - 'rsrc/css/core/core.css' => 'a708bd25', + 'rsrc/css/core/core.css' => 'b3a5928e', 'rsrc/css/core/remarkup.css' => '3480e1fe', 'rsrc/css/core/syntax.css' => '548567f6', 'rsrc/css/core/z-index.css' => 'ac3bfcd4', @@ -772,7 +772,7 @@ return array( 'phabricator-busy' => '5202e831', 'phabricator-chatlog-css' => 'abdc76ee', 'phabricator-content-source-view-css' => 'cdf0d579', - 'phabricator-core-css' => 'a708bd25', + 'phabricator-core-css' => 'b3a5928e', 'phabricator-countdown-css' => 'bff8012f', 'phabricator-darklog' => '3b869402', 'phabricator-darkmessage' => '26cd4b73', diff --git a/webroot/rsrc/css/core/core.css b/webroot/rsrc/css/core/core.css index ccb3d1697f..4a9d3b394b 100644 --- a/webroot/rsrc/css/core/core.css +++ b/webroot/rsrc/css/core/core.css @@ -84,7 +84,7 @@ h2 { } a { - -moz-outline-style: none; + outline-style: none; text-decoration: none; color: {$anchor}; cursor: pointer; From 2d635fb76e9b20cce53ed68fe1dfd4daa79aa8c2 Mon Sep 17 00:00:00 2001 From: Valerio Bozzolan Date: Mon, 16 Oct 2023 08:40:23 +0200 Subject: [PATCH 49/93] Dashboard Panel: fix first tab sometime not opened anymore Summary: After this change the first Tab ID is always selected, so we don't risk to have no tabs opened by default under some corner cases. This is vaguely better than the original logic that relied on the fact that (0=="0") is true. Besides being a vaguely weird emoticon as well, now that I look at it better. Original logic: https://we.phorge.it/source/phorge/browse/master/src/applications/dashboard/paneltype/PhabricatorDashboardTabsPanelType.php;c43618a3a8bb021936fad687f04cb1a95faa23e4$289 This fixes a regression that appeared in the cute Wikimedia Phabricator (that now is really Wikimedia Phorge). Their homepage should be gorgeous again, without blank space due to unopened silly tabs. Closes T15651 Test Plan: - Have a Tab Panel (/dashboard/panel/). - Be sure that the first Tab is automatically selected (again?) Reviewers: aklapper, O1 Blessed Committers, avivey Reviewed By: O1 Blessed Committers, avivey Subscribers: tobiaswiese, Matthew, Cigaryno Maniphest Tasks: T15651 Differential Revision: https://we.phorge.it/D25447 --- .../paneltype/PhabricatorDashboardTabsPanelType.php | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/applications/dashboard/paneltype/PhabricatorDashboardTabsPanelType.php b/src/applications/dashboard/paneltype/PhabricatorDashboardTabsPanelType.php index 3cf73b539e..6b4f2fe5d6 100644 --- a/src/applications/dashboard/paneltype/PhabricatorDashboardTabsPanelType.php +++ b/src/applications/dashboard/paneltype/PhabricatorDashboardTabsPanelType.php @@ -85,10 +85,12 @@ final class PhabricatorDashboardTabsPanelType $rename_uri = id(new PhutilURI($rename_uri)) ->replaceQueryParam('contextPHID', $context_phid); - $selected = 0; - $key_list = array_keys($config); + // In the future we may persist which panel was selected. + // At the moment we have always selected the first one. + $selected = (string)head($key_list); + $next_keys = array(); $prev_keys = array(); for ($ii = 0; $ii < count($key_list); $ii++) { @@ -111,7 +113,8 @@ final class PhabricatorDashboardTabsPanelType $name = pht('Unnamed Tab'); } - $is_selected = (string)$idx === (string)$selected; + // The $idx can be something like "0", "1" or "asdasd98". + $is_selected = (string)$idx === $selected; $tab_view = id(new PHUIListItemView()) ->setHref('#') @@ -282,7 +285,8 @@ final class PhabricatorDashboardTabsPanelType $panel_content = pht('(Invalid Panel)'); } - $is_selected = (string)$idx === (string)$selected; + // Note that $idx can be something like "0", "1" or "asdasd98". + $is_selected = (string)$idx === $selected; $content_id = celerity_generate_unique_node_id(); From 7b0021a03cb28cf039d05530844874773e8258c2 Mon Sep 17 00:00:00 2001 From: Andre Klapper Date: Sat, 16 Sep 2023 14:13:21 +0200 Subject: [PATCH 50/93] Fix "Undefined index" exception setting Meme text Summary: `strlen()` was used in Phabricator to check if a generic value is a non-empty string. This behavior is deprecated since PHP 8.1. Phorge adopts `phutil_nonempty_string()` as a replacement. Note: this may highlight other absurd input values that might be worth correcting instead of just ignoring. If phutil_nonempty_string() throws an exception in your instance, report it to Phorge to evaluate and fix that specific corner case. ``` EXCEPTION: (RuntimeException) Undefined index: above at [/src/error/PhutilErrorHandler.php:251] arcanist(), phorge() #0 <#2> PhutilErrorHandler::handleError(integer, string, string, integer, array) called at [/src/applications/macro/engine/PhabricatorMemeEngine.php:276] ``` Closes T15637 Test Plan: Create a meme called "angrycat" from the /macro/ page, and try a comment like this, expecting no nuclear implosion: {meme, src=angrycat, below=} {meme, src=angrycat, above=} {meme, src=angrycat, below=, above=} {meme, src=angrycat, below= , above= } {meme, src=angrycat, below=asd} {meme, src=angrycat, above=asd} {meme, src=angrycat, above=asd, below=dsa} {meme, src=angrycat, above= asd , below= dsa } Also carefully read the code with your big eyes, keeping in mind that strlen does not accept passing `null` in PHP 8, and looking at what we did in rPb4cfe56f03b44615ac9251aed8d74bf13b085051. Reviewers: O1 Blessed Committers, valerio.bozzolan Reviewed By: O1 Blessed Committers, valerio.bozzolan Subscribers: tobiaswiese, valerio.bozzolan, Matthew, Cigaryno Maniphest Tasks: T15637 Differential Revision: https://we.phorge.it/D25437 --- src/applications/macro/engine/PhabricatorMemeEngine.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/applications/macro/engine/PhabricatorMemeEngine.php b/src/applications/macro/engine/PhabricatorMemeEngine.php index e1befc20a2..71a45033da 100644 --- a/src/applications/macro/engine/PhabricatorMemeEngine.php +++ b/src/applications/macro/engine/PhabricatorMemeEngine.php @@ -273,7 +273,7 @@ final class PhabricatorMemeEngine extends Phobject { $size = $metrics['size']; $above = $this->getAboveText(); - if (strlen($above)) { + if ($above !== null && phutil_nonempty_string(trim($above))) { $x = (int)floor(($dx - $metrics['text']['above']['width']) / 2); $y = $metrics['text']['above']['height'] + 12; @@ -281,7 +281,7 @@ final class PhabricatorMemeEngine extends Phobject { } $below = $this->getBelowText(); - if (strlen($below)) { + if ($below !== null && phutil_nonempty_string(trim($below))) { $x = (int)floor(($dx - $metrics['text']['below']['width']) / 2); $y = $dy - 12 - $metrics['text']['below']['descend']; From 318d7a61feab3f632febb76e915c4e19dabf53f4 Mon Sep 17 00:00:00 2001 From: sten Date: Wed, 25 Oct 2023 09:40:36 +0100 Subject: [PATCH 51/93] Fix PhabricatorAuthCSRFEngine.php strncmp(null) PHP 8.1 error Summary: Update PhabricatorAuthCSRFEngine.php such that it doesn't fall over when provided with a null CSRF token under PHP 8.1 Fixes T15654 Test Plan: Do a POST request to phorge. Reviewers: O1 Blessed Committers, valerio.bozzolan Reviewed By: O1 Blessed Committers, valerio.bozzolan Subscribers: tobiaswiese, valerio.bozzolan, Matthew, Cigaryno Maniphest Tasks: T15654 Differential Revision: https://we.phorge.it/D25449 --- src/applications/auth/engine/PhabricatorAuthCSRFEngine.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/applications/auth/engine/PhabricatorAuthCSRFEngine.php b/src/applications/auth/engine/PhabricatorAuthCSRFEngine.php index fcb8c13ab7..856b334039 100644 --- a/src/applications/auth/engine/PhabricatorAuthCSRFEngine.php +++ b/src/applications/auth/engine/PhabricatorAuthCSRFEngine.php @@ -47,7 +47,10 @@ final class PhabricatorAuthCSRFEngine extends Phobject { // We expect a BREACH-mitigating token. See T3684. $breach_prefix = $this->getBREACHPrefix(); $breach_prelen = strlen($breach_prefix); - if (strncmp($token, $breach_prefix, $breach_prelen) !== 0) { + if ( + $token === null || + strncmp($token, $breach_prefix, $breach_prelen) !== 0 + ) { return false; } From 629fa368cb9ae2331028e1504bb95f55a50d7d4b Mon Sep 17 00:00:00 2001 From: Valerio Bozzolan Date: Wed, 25 Oct 2023 19:07:44 +0200 Subject: [PATCH 52/93] Calendar: fix creation of ICS Files Summary: It seems that, in an attempt to make ICS URI(s) editable, we broke the ability to manually import ICS files. Whops. The cause is, the URI needs to be put inside its dedicated import engine, and not the general one. Since the intention of T15137 was to be able to edit this field, we have done that in the right way this time. So, you see the field, not just in creation mode. Thanks to the kind aklapper for reporting. Ref T15137 Closes T15619 Rollback 02a4f8b0c8f1279fc0040ad8077942fd8b0d948b Test Plan: - visit /calendar/import/ and: - create/edit an ICS File Import (now works again) - create/edit an ICS URI Import (still work) - try looking at an "ICS Import page" as author (URI still visible) - try looking at an "ICS Import page" without Edit permissions (URI still omitted correctly) Reviewers: aklapper, O1 Blessed Committers, 20after4 Reviewed By: aklapper, O1 Blessed Committers, 20after4 Subscribers: 20after4, tobiaswiese, Matthew, Cigaryno Maniphest Tasks: T15619, T15137 Differential Revision: https://we.phorge.it/D25448 --- .../PhabricatorCalendarImportEditEngine.php | 15 ------------ .../PhabricatorCalendarICSURIImportEngine.php | 23 +++++++++++-------- 2 files changed, 13 insertions(+), 25 deletions(-) diff --git a/src/applications/calendar/editor/PhabricatorCalendarImportEditEngine.php b/src/applications/calendar/editor/PhabricatorCalendarImportEditEngine.php index 9a4a7c0107..7be3969671 100644 --- a/src/applications/calendar/editor/PhabricatorCalendarImportEditEngine.php +++ b/src/applications/calendar/editor/PhabricatorCalendarImportEditEngine.php @@ -83,12 +83,6 @@ final class PhabricatorCalendarImportEditEngine $engine = $object->getEngine(); $can_trigger = $engine->supportsTriggers($object); - // calendar URI import - // note that it can contains a secret token - // if we are here you have enough privileges to edit and see the value - $uri_key = PhabricatorCalendarImportICSURITransaction::PARAMKEY_URI; - $uri = $object->getParameter($uri_key); - $fields = array( id(new PhabricatorTextEditField()) ->setKey('name') @@ -100,15 +94,6 @@ final class PhabricatorCalendarImportEditEngine ->setConduitTypeDescription(pht('New import name.')) ->setPlaceholder($object->getDisplayName()) ->setValue($object->getName()), - id(new PhabricatorTextEditField()) - ->setKey('uri') - ->setLabel(pht('URI')) - ->setDescription(pht('URI to import.')) - ->setTransactionType( - PhabricatorCalendarImportICSURITransaction::TRANSACTIONTYPE) - ->setConduitDescription(pht('URI to import.')) - ->setConduitTypeDescription(pht('New URI.')) - ->setValue($uri), id(new PhabricatorBoolEditField()) ->setKey('disabled') ->setOptions(pht('Active'), pht('Disabled')) diff --git a/src/applications/calendar/import/PhabricatorCalendarICSURIImportEngine.php b/src/applications/calendar/import/PhabricatorCalendarICSURIImportEngine.php index bd52ec5bc2..6c992e0836 100644 --- a/src/applications/calendar/import/PhabricatorCalendarICSURIImportEngine.php +++ b/src/applications/calendar/import/PhabricatorCalendarICSURIImportEngine.php @@ -58,16 +58,19 @@ final class PhabricatorCalendarICSURIImportEngine PhabricatorCalendarImport $import) { $fields = array(); - if ($engine->getIsCreate()) { - $fields[] = id(new PhabricatorTextEditField()) - ->setKey('uri') - ->setLabel(pht('URI')) - ->setDescription(pht('URI to import.')) - ->setTransactionType( - PhabricatorCalendarImportICSURITransaction::TRANSACTIONTYPE) - ->setConduitDescription(pht('URI to import.')) - ->setConduitTypeDescription(pht('New URI.')); - } + // If you are here, you already have the "can edit" capability. + // So you are supposed to be able to edit again your Calendar import URI. + $uri_key = PhabricatorCalendarImportICSURITransaction::PARAMKEY_URI; + $uri = $import->getParameter($uri_key); + $fields[] = id(new PhabricatorTextEditField()) + ->setKey('uri') + ->setLabel(pht('URI')) + ->setDescription(pht('URI to import.')) + ->setTransactionType( + PhabricatorCalendarImportICSURITransaction::TRANSACTIONTYPE) + ->setConduitDescription(pht('URI to import.')) + ->setConduitTypeDescription(pht('New URI.')) + ->setValue($uri); return $fields; } From d4b110af260caab56936aab543041b0904e4d02a Mon Sep 17 00:00:00 2001 From: Andre Klapper Date: Thu, 26 Oct 2023 22:44:48 +0200 Subject: [PATCH 53/93] Remove unused variable $info in DiffusionCloneController.php Summary: Left-over from rPa6b550ba0394284441ee55d11e276a05eb568ad9 Closes T15655 Test Plan: Carefully read the source code file to look out for another appearance; after hours of fruitless searching get slightly disappointed. Reviewers: O1 Blessed Committers, avivey Reviewed By: O1 Blessed Committers, avivey Subscribers: tobiaswiese, valerio.bozzolan, Matthew, Cigaryno Maniphest Tasks: T15655 Differential Revision: https://we.phorge.it/D25451 --- .../diffusion/controller/DiffusionCloneController.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/applications/diffusion/controller/DiffusionCloneController.php b/src/applications/diffusion/controller/DiffusionCloneController.php index 8bc4faa1a2..bf118bcf6d 100644 --- a/src/applications/diffusion/controller/DiffusionCloneController.php +++ b/src/applications/diffusion/controller/DiffusionCloneController.php @@ -49,8 +49,6 @@ final class DiffusionCloneController extends DiffusionController { ->appendChild(pht('Repository has no URIs set.')); } - $info = null; - // Try to load alternatives. This may fail for repositories which have not // cloned yet. If it does, just ignore it and continue. try { From 222a6fea0a1d9318198fe73a0501cf6444420ce3 Mon Sep 17 00:00:00 2001 From: Andre Klapper Date: Sat, 4 Nov 2023 19:34:00 +0100 Subject: [PATCH 54/93] Fix PHP 8.1 "strlen(null)" exception on Diffusion repo URIs page after repo creation Summary: `strlen()` was used in Phabricator to check if a generic value is a non-empty string. This behavior is deprecated since PHP 8.1. Phorge adopts `phutil_nonempty_string()` as a replacement. Note: this may highlight other absurd input values that might be worth correcting instead of just ignoring. If phutil_nonempty_string() throws an exception in your instance, report it to Phorge to evaluate and fix that specific corner case. ``` ERROR 8192: strlen(): Passing null to parameter #1 ($string) of type string is deprecated at [/var/www/html/phorge/phorge/src/applications/repository/storage/PhabricatorRepository.php:348] ``` Closes T15658 Test Plan: Create an empty new Git repository, go to its URIs management page. Reviewers: O1 Blessed Committers, speck Reviewed By: O1 Blessed Committers, speck Subscribers: tobiaswiese, valerio.bozzolan, Matthew, Cigaryno Maniphest Tasks: T15658 Differential Revision: https://we.phorge.it/D25454 --- src/applications/repository/storage/PhabricatorRepository.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/applications/repository/storage/PhabricatorRepository.php b/src/applications/repository/storage/PhabricatorRepository.php index 4a1c923622..b2855c0c06 100644 --- a/src/applications/repository/storage/PhabricatorRepository.php +++ b/src/applications/repository/storage/PhabricatorRepository.php @@ -345,12 +345,12 @@ final class PhabricatorRepository extends PhabricatorRepositoryDAO // Make some reasonable effort to produce reasonable default directory // names from repository names. - if (!strlen($name)) { + if (!phutil_nonempty_string($name)) { $name = $this->getName(); $name = phutil_utf8_strtolower($name); $name = preg_replace('@[ -/:->]+@', '-', $name); $name = trim($name, '-'); - if (!strlen($name)) { + if (!phutil_nonempty_string($name)) { $name = $this->getCallsign(); } } From 887e344c19af9ee6f4855227f8a215a491974794 Mon Sep 17 00:00:00 2001 From: Andre Klapper Date: Sat, 28 Oct 2023 20:23:42 +0200 Subject: [PATCH 55/93] Fix project page 404 after rename and removing new name from alias slugs Summary: When renaming a project to a slug already listed under Additional hashtags and explicitly also removing that to-become slug, accessing the project via the URL `/tag/projectname/` returned a 404 until someone added the current project name explicitly under "Additional hashtags" again. In that case, do not remove the alternative hashtag to avoid the 404. Closes T15636 Test Plan: See steps in https://we.phorge.it/T15636 Reviewers: O1 Blessed Committers, speck Reviewed By: O1 Blessed Committers, speck Subscribers: speck, tobiaswiese, valerio.bozzolan, Matthew, Cigaryno Maniphest Tasks: T15636 Differential Revision: https://we.phorge.it/D25453 --- .../project/editor/PhabricatorProjectTransactionEditor.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/applications/project/editor/PhabricatorProjectTransactionEditor.php b/src/applications/project/editor/PhabricatorProjectTransactionEditor.php index eb57c39b2c..9c6e5cf4cc 100644 --- a/src/applications/project/editor/PhabricatorProjectTransactionEditor.php +++ b/src/applications/project/editor/PhabricatorProjectTransactionEditor.php @@ -295,6 +295,12 @@ final class PhabricatorProjectTransactionEditor } public function removeSlugs(PhabricatorProject $project, array $slugs) { + // Do not allow removing the project's primary slug which the edit form + // may allow through a series of renames/moves. See T15636 + if (($key = array_search($project->getPrimarySlug(), $slugs)) !== false) { + unset($slugs[$key]); + } + if (!$slugs) { return; } From 37ecdf23369740a740ca8d9f3bf7daef6f7077bd Mon Sep 17 00:00:00 2001 From: "roberto.urbani" Date: Mon, 6 Nov 2023 08:26:37 +0000 Subject: [PATCH 56/93] Improving UX for ignoring timezone conflicts Summary: When there is a new timezone conflict, you will be able to ignore it with a checkbox. Fix T15349 Preview: {F343198} Test Plan: Having a conflicting timezone, click the notification so the usual popup appears. There is a checkbox, leave it checked to ignore the current conflict, uncheck to manually resolve the conflict by selecting one of the available timezones. Reviewers: O1 Blessed Committers, valerio.bozzolan, avivey Reviewed By: O1 Blessed Committers, valerio.bozzolan, avivey Subscribers: speck, waldyrious, avivey, tobiaswiese, valerio.bozzolan, Matthew, Cigaryno Maniphest Tasks: T15349 Differential Revision: https://we.phorge.it/D25420 --- .../PhabricatorSettingsTimezoneController.php | 22 ++++++++++++++----- 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/src/applications/settings/controller/PhabricatorSettingsTimezoneController.php b/src/applications/settings/controller/PhabricatorSettingsTimezoneController.php index 8ae2704161..9cde82fdf0 100644 --- a/src/applications/settings/controller/PhabricatorSettingsTimezoneController.php +++ b/src/applications/settings/controller/PhabricatorSettingsTimezoneController.php @@ -31,11 +31,12 @@ final class PhabricatorSettingsTimezoneController $did_calibrate = false; if ($request->isFormPost()) { $timezone = $request->getStr('timezone'); + $ignore_conflict_checkbox = $request->getInt('ignoreConflict'); $pref_ignore = PhabricatorTimezoneIgnoreOffsetSetting::SETTINGKEY; $pref_timezone = PhabricatorTimezoneSetting::SETTINGKEY; - if ($timezone == 'ignore') { + if ($timezone === 'ignore' || $ignore_conflict_checkbox) { $this->writeSettings( array( $pref_ignore => $client_offset, @@ -83,20 +84,29 @@ final class PhabricatorSettingsTimezoneController $guess = 'ignore'; } - $current_zone = $viewer->getTimezoneIdentifier(); - $current_zone = phutil_tag('strong', array(), $current_zone); + $current_zone_identifier = $viewer->getTimezoneIdentifier(); + $current_zone_formatted = phutil_tag( + 'strong', + array(), + $current_zone_identifier); $form = id(new AphrontFormView()) ->appendChild( id(new AphrontFormMarkupControl()) ->setLabel(pht('Current Setting')) - ->setValue($current_zone)) + ->setValue($current_zone_formatted)) ->appendChild( id(new AphrontFormSelectControl()) ->setName('timezone') ->setLabel(pht('New Setting')) ->setOptions($options) - ->setValue($guess)); + ->setValue($guess)) + ->appendChild(id(new AphrontFormCheckboxControl()) + ->addCheckbox( + 'ignoreConflict', + 1, + pht('Ignore New Setting and Keep %s', $current_zone_identifier))); + return $this->newDialog() ->setTitle(pht('Adjust Timezone')) @@ -110,7 +120,7 @@ final class PhabricatorSettingsTimezoneController $this->formatOffset($server_offset))) ->appendForm($form) ->addCancelButton(pht('Cancel')) - ->addSubmitButton(pht('Change Timezone')); + ->addSubmitButton(pht('Confirm')); } private function formatOffset($offset) { From ce5e0f3e333e87719261837ad994c00d43507349 Mon Sep 17 00:00:00 2001 From: Zero King Date: Wed, 8 Nov 2023 21:31:39 +0800 Subject: [PATCH 57/93] Fix doc link to Restarting Phorge Summary: See Q81. Link to /diviner/find/ could not find the documentation because it was renamed to "Restarting Phorge". Test Plan: 1. Uninstall optional PHP extension zip and restart Phorge 2. Vist /config/issue/ and click on a missing extension issue 3. Click on the documentation link to Restarting Reviewers: O1 Blessed Committers, valerio.bozzolan, speck Reviewed By: O1 Blessed Committers, valerio.bozzolan, speck Subscribers: speck, tobiaswiese, valerio.bozzolan, Matthew, Cigaryno Differential Revision: https://we.phorge.it/D25459 --- src/applications/config/view/PhabricatorSetupIssueView.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/applications/config/view/PhabricatorSetupIssueView.php b/src/applications/config/view/PhabricatorSetupIssueView.php index bfeae20684..e07e33b3d0 100644 --- a/src/applications/config/view/PhabricatorSetupIssueView.php +++ b/src/applications/config/view/PhabricatorSetupIssueView.php @@ -603,14 +603,14 @@ final class PhabricatorSetupIssueView extends AphrontView { } private function renderRestartLink() { - $doc_href = PhabricatorEnv::getDoclink('Restarting Phabricator'); + $doc_href = PhabricatorEnv::getDoclink('Restarting Phorge'); return phutil_tag( 'a', array( 'href' => $doc_href, 'target' => '_blank', ), - pht('Restarting Phabricator')); + pht('Restarting')); } } From dfa15726ea5afec47e5062a1feaf2ef0cd75c8ea Mon Sep 17 00:00:00 2001 From: Andre Klapper Date: Sun, 5 Nov 2023 15:36:10 +0100 Subject: [PATCH 58/93] Fix cursor paging issue in Given Token query call Summary: The "Query" class for Given Token is missing a "withIDs()" method. `Call to undefined method PhabricatorTokenGivenQuery::withIDs() at [PhabricatorCursorPagedPolicyAwareQuery.php:120]` Closes T15652 Test Plan: Go to the Token page and pass a URL parameter, such as `/token/given/?after=3` Reviewers: O1 Blessed Committers, speck Reviewed By: O1 Blessed Committers, speck Subscribers: speck, tobiaswiese, valerio.bozzolan, Matthew, Cigaryno Maniphest Tasks: T15652 Differential Revision: https://we.phorge.it/D25455 --- .../tokens/query/PhabricatorTokenGivenQuery.php | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/applications/tokens/query/PhabricatorTokenGivenQuery.php b/src/applications/tokens/query/PhabricatorTokenGivenQuery.php index 0e6ad9eb54..14e8016cf1 100644 --- a/src/applications/tokens/query/PhabricatorTokenGivenQuery.php +++ b/src/applications/tokens/query/PhabricatorTokenGivenQuery.php @@ -3,10 +3,16 @@ final class PhabricatorTokenGivenQuery extends PhabricatorCursorPagedPolicyAwareQuery { + private $ids; private $authorPHIDs; private $objectPHIDs; private $tokenPHIDs; + public function withIDs(array $ids) { + $this->ids = $ids; + return $this; + } + public function withTokenPHIDs(array $token_phids) { $this->tokenPHIDs = $token_phids; return $this; @@ -29,6 +35,13 @@ final class PhabricatorTokenGivenQuery protected function buildWhereClauseParts(AphrontDatabaseConnection $conn) { $where = parent::buildWhereClauseParts($conn); + if ($this->ids !== null) { + $where[] = qsprintf( + $conn, + 'id IN (%Ld)', + $this->ids); + } + if ($this->authorPHIDs !== null) { $where[] = qsprintf( $conn, From 8507d3a95072db363add43d8a397dfd502c3db37 Mon Sep 17 00:00:00 2001 From: Valerio Bozzolan Date: Thu, 9 Nov 2023 21:04:06 +0100 Subject: [PATCH 59/93] Fix Exception in Chat room when you are not a Participant Summary: After this change you can lurk in public chats, and receive notifications, without crashing your planet. Fix exception "Undefined index: PHID-USER-..." shown to newcomers when they are receiving messages from a public Chat they are not members of. Closes T15497 Test Plan: - Have the Notification server (Aphlict) enabled and running. https://we.phorge.it/book/phorge/article/notifications/ - Be user Alice and visit a Conpherence Room. Alice must be not a participant. - Be user Bob and send a message in that Room. Now Alice does not see a crash anymore, but the message from Bob. Reviewers: O1 Blessed Committers, speck Reviewed By: O1 Blessed Committers, speck Subscribers: speck, tobiaswiese, Matthew, Cigaryno Maniphest Tasks: T15497 Differential Revision: https://we.phorge.it/D25408 --- .../controller/ConpherenceUpdateController.php | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/applications/conpherence/controller/ConpherenceUpdateController.php b/src/applications/conpherence/controller/ConpherenceUpdateController.php index a792a5a4d4..6d838e72bc 100644 --- a/src/applications/conpherence/controller/ConpherenceUpdateController.php +++ b/src/applications/conpherence/controller/ConpherenceUpdateController.php @@ -328,7 +328,12 @@ final class ConpherenceUpdateController ->executeOne(); $non_update = false; - $participant = $conpherence->getParticipant($user->getPHID()); + + // The User is always available. The Participant may not. See: + // User: it's you, lurking the Chat (maybe it's a public chat). + // Participant: it's you, if you are a Chat Member. + // https://we.phorge.it/T15497 + $participant = $conpherence->getParticipantIfExists($user->getPHID()); if ($need_transactions && $conpherence->getTransactions()) { $data = ConpherenceTransactionRenderer::renderTransactions( @@ -336,7 +341,7 @@ final class ConpherenceUpdateController $conpherence); $key = PhabricatorConpherenceColumnMinimizeSetting::SETTINGKEY; $minimized = $user->getUserSetting($key); - if (!$minimized) { + if (!$minimized && $participant) { $participant->markUpToDate($conpherence); } } else if ($need_transactions) { From 8092d90c79fc79e8e17b0f50a449e7d2e204acde Mon Sep 17 00:00:00 2001 From: Waldir Pimenta Date: Thu, 9 Nov 2023 23:05:28 +0000 Subject: [PATCH 60/93] Adjust message in timezone conflict form Summary: This applies a suggestion initially proposed in https://we.phorge.it/D25420#12264 Test Plan: - Change your browser/system timezone to differ from your Phorge profile timezone - Click the notice that Phorge shows at the bottom left about the timezone mismatch - Confirm that the form text has been changed as per the diff in this revision Reviewers: O1 Blessed Committers, valerio.bozzolan Reviewed By: O1 Blessed Committers, valerio.bozzolan Subscribers: aklapper, tobiaswiese, valerio.bozzolan, Matthew, Cigaryno Differential Revision: https://we.phorge.it/D25458 --- .../controller/PhabricatorSettingsTimezoneController.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/applications/settings/controller/PhabricatorSettingsTimezoneController.php b/src/applications/settings/controller/PhabricatorSettingsTimezoneController.php index 9cde82fdf0..0ed286da02 100644 --- a/src/applications/settings/controller/PhabricatorSettingsTimezoneController.php +++ b/src/applications/settings/controller/PhabricatorSettingsTimezoneController.php @@ -114,8 +114,8 @@ final class PhabricatorSettingsTimezoneController ->appendParagraph( pht( 'Your browser timezone (%s) differs from your profile timezone '. - '(%s). You can ignore this conflict or adjust your profile setting '. - 'to match your client.', + '(%s). You can adjust your profile setting to match your browser, '. + 'or ignore this conflict to keep your current profile setting.', $this->formatOffset($client_offset), $this->formatOffset($server_offset))) ->appendForm($form) From 0729aa574bfd05bdd510ff48717a92a349f20640 Mon Sep 17 00:00:00 2001 From: Waldir Pimenta Date: Fri, 10 Nov 2023 09:13:09 +0000 Subject: [PATCH 61/93] Remove mention of Phabricator in the Auth setup check Summary: The authentication setup check, available at /config/issue/auth.config-unlocked/, contained a reference to Phabricator in the prompt of the command line hint to resolve the issue. Similar checks only showed the prompt symbol, not the directory, so this one was changed to match. Ref T15006 Test Plan: - Run `./bin/auth unlock` - Visit /config/issue/auth.config-unlocked/ - Notice that, with this patch, "phabricator" no longer appears in the prompt prefix for the suggested fix command at the end of the page. Reviewers: O1 Blessed Committers, valerio.bozzolan, speck Reviewed By: O1 Blessed Committers, valerio.bozzolan, speck Subscribers: avivey, tobiaswiese, Matthew, valerio.bozzolan, Cigaryno Maniphest Tasks: T15006 Differential Revision: https://we.phorge.it/D25425 --- src/applications/config/check/PhabricatorAuthSetupCheck.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/applications/config/check/PhabricatorAuthSetupCheck.php b/src/applications/config/check/PhabricatorAuthSetupCheck.php index e2b076944e..b971404c38 100644 --- a/src/applications/config/check/PhabricatorAuthSetupCheck.php +++ b/src/applications/config/check/PhabricatorAuthSetupCheck.php @@ -74,7 +74,7 @@ final class PhabricatorAuthSetupCheck extends PhabricatorSetupCheck { ->addRelatedPhabricatorConfig('auth.lock-config') ->addCommand( hsprintf( - 'phabricator/ $ ./bin/auth lock')); + '$ ./bin/auth lock')); } } } From 87e9c936ad1c98c232dd1632ca649f2d6a227c4d Mon Sep 17 00:00:00 2001 From: Andre Klapper Date: Thu, 9 Nov 2023 20:23:03 +0100 Subject: [PATCH 62/93] Make "git cat-file" exception messages include repository monogram/slug Summary: When throwing an exception related to output provided by `git cat-file`, include the repository monogram to allow potentially debugging in Git. Closes T15661 Test Plan: Unclear. Basically: "have a broken Git repository in Diffusion". (However this patch changes a message only shown in case of an exception, so in the worst case we'd break the exception via an exception.) Reviewers: O1 Blessed Committers, speck Reviewed By: O1 Blessed Committers, speck Subscribers: speck, tobiaswiese, valerio.bozzolan, Matthew, Cigaryno Maniphest Tasks: T15661 Differential Revision: https://we.phorge.it/D25460 --- .../lowlevel/DiffusionLowLevelResolveRefsQuery.php | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/applications/diffusion/query/lowlevel/DiffusionLowLevelResolveRefsQuery.php b/src/applications/diffusion/query/lowlevel/DiffusionLowLevelResolveRefsQuery.php index 0bbba1dc18..899e69d49b 100644 --- a/src/applications/diffusion/query/lowlevel/DiffusionLowLevelResolveRefsQuery.php +++ b/src/applications/diffusion/query/lowlevel/DiffusionLowLevelResolveRefsQuery.php @@ -140,8 +140,9 @@ final class DiffusionLowLevelResolveRefsQuery if (count($lines) !== count($unresolved)) { throw new Exception( pht( - 'Unexpected line count from `%s`!', - 'git cat-file')); + 'Unexpected line count from `%s` in %s!', + 'git cat-file', + $repository->getMonogram())); } $hits = array(); @@ -153,8 +154,9 @@ final class DiffusionLowLevelResolveRefsQuery if (count($parts) < 2) { throw new Exception( pht( - 'Failed to parse `%s` output: %s', + 'Failed to parse `%s` output in %s: %s', 'git cat-file', + $repository->getMonogram(), $line)); } list($identifier, $type) = $parts; @@ -177,8 +179,9 @@ final class DiffusionLowLevelResolveRefsQuery default: throw new Exception( pht( - 'Unexpected object type from `%s`: %s', + 'Unexpected object type from `%s` in %s: %s', 'git cat-file', + $repository->getMonogram(), $line)); } From c97a50472c5b0c9f441221c6cec9d9baa5f290b8 Mon Sep 17 00:00:00 2001 From: Zero King Date: Sat, 11 Nov 2023 10:20:35 +0800 Subject: [PATCH 63/93] Correct default database prefix in documentation Summary: Default value of `storage.default-namespace` is still `phabricator`. Correct documentation about this. Test Plan: Compare documentation with src/applications/config/option/PhabricatorMySQLConfigOptions.php. Reviewers: O1 Blessed Committers, speck Reviewed By: O1 Blessed Committers, speck Subscribers: speck, tobiaswiese, valerio.bozzolan, Matthew, Cigaryno Differential Revision: https://we.phorge.it/D25463 --- src/docs/contributor/database.diviner | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/docs/contributor/database.diviner b/src/docs/contributor/database.diviner index dc553678a8..6572e42fc1 100644 --- a/src/docs/contributor/database.diviner +++ b/src/docs/contributor/database.diviner @@ -28,7 +28,7 @@ Databases ========= Each Phorge application has its own database. The names are prefixed by -`phorge_` (this is configurable). +`phabricator_` (this is configurable with `storage.default-namespace`). Phorge uses a separate database for each application. To understand why, see @{article:Why does Phorge need so many databases?}. From 90f651d669e447f6263574eea672827503f7b6d3 Mon Sep 17 00:00:00 2001 From: Andre Klapper Date: Thu, 26 Oct 2023 21:26:11 +0200 Subject: [PATCH 64/93] Add Diffusion policy capability "Can Edit and View Identities" Summary: Make it possible not to allow anyone to edit Diffusion identities. Make it possible not to allow anyone to view other users' email addresses. Closes T15443 Test Plan: * As an admin, go to `/applications/view/PhabricatorDiffusionApplication/` and see new policy "Can Edit and View Identities" set to "All Users" (as implicitly before) * As an admin, go to `/applications/view/PhabricatorDiffusionApplication/` and change "Can Edit and View Identities" from "All Users" to "Administrators" * As a non-admin, go to `/diffusion/identity/` and try to select the disabled "Create Identity" button; get an error message clicking it due to lack of permissions * Given there is at least one identity defined, as a non-admin, go directly to `/diffusion/identity/view/1/` and get "You do not have permission to view this object." * Given there is at least one identity defined, as a non-admin, go directly to `/diffusion/identity/edit/1/` and get "You do not have permission to view this object." * As a non-admin, go directly to `/diffusion/identity/edit/form/default/` and get "You do not have permission to edit this object." * As a non-admin, go directly to `/diffusion/identity/` and get "No Identities found." instead of seeing the existing identities listed. * As an admin, go to `/diffusion/identity/` and still see the existing identities listed. * As an admin, go to `/diffusion/identity/`, select "Create Identity" to go to `/diffusion/identity/edit/` and see the "Create Identity" page (though broken; see T15453) * As an admin, go to `/diffusion/identity/view/1/` and still see the existing identity. * As an admin, go to `/diffusion/identity/edit/1/` and successfully edit the existing identity. Reviewers: O1 Blessed Committers, speck, valerio.bozzolan Reviewed By: O1 Blessed Committers, speck, valerio.bozzolan Subscribers: speck, tobiaswiese, valerio.bozzolan, Matthew, Cigaryno Maniphest Tasks: T15443 Differential Revision: https://we.phorge.it/D25450 --- src/__phutil_library_map__.php | 2 ++ .../PhabricatorDiffusionApplication.php | 3 +++ ...catorRepositoryIdentityEditViewCapability.php | 16 ++++++++++++++++ .../PhabricatorRepositoryIdentityEditEngine.php | 3 ++- .../storage/PhabricatorRepositoryIdentity.php | 5 ++++- 5 files changed, 27 insertions(+), 2 deletions(-) create mode 100644 src/applications/repository/capability/PhabricatorRepositoryIdentityEditViewCapability.php diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php index d223f47515..ad0d8fc937 100644 --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -4628,6 +4628,7 @@ phutil_register_library_map(array( 'PhabricatorRepositoryIdentityAssignTransaction' => 'applications/repository/xaction/PhabricatorRepositoryIdentityAssignTransaction.php', 'PhabricatorRepositoryIdentityChangeWorker' => 'applications/repository/worker/PhabricatorRepositoryIdentityChangeWorker.php', 'PhabricatorRepositoryIdentityEditEngine' => 'applications/repository/engine/PhabricatorRepositoryIdentityEditEngine.php', + 'PhabricatorRepositoryIdentityEditViewCapability' => 'applications/repository/capability/PhabricatorRepositoryIdentityEditViewCapability.php', 'PhabricatorRepositoryIdentityFerretEngine' => 'applications/repository/search/PhabricatorRepositoryIdentityFerretEngine.php', 'PhabricatorRepositoryIdentityPHIDType' => 'applications/repository/phid/PhabricatorRepositoryIdentityPHIDType.php', 'PhabricatorRepositoryIdentityQuery' => 'applications/repository/query/PhabricatorRepositoryIdentityQuery.php', @@ -11325,6 +11326,7 @@ phutil_register_library_map(array( 'PhabricatorRepositoryIdentityAssignTransaction' => 'PhabricatorRepositoryIdentityTransactionType', 'PhabricatorRepositoryIdentityChangeWorker' => 'PhabricatorWorker', 'PhabricatorRepositoryIdentityEditEngine' => 'PhabricatorEditEngine', + 'PhabricatorRepositoryIdentityEditViewCapability' => 'PhabricatorPolicyCapability', 'PhabricatorRepositoryIdentityFerretEngine' => 'PhabricatorFerretEngine', 'PhabricatorRepositoryIdentityPHIDType' => 'PhabricatorPHIDType', 'PhabricatorRepositoryIdentityQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', diff --git a/src/applications/diffusion/application/PhabricatorDiffusionApplication.php b/src/applications/diffusion/application/PhabricatorDiffusionApplication.php index e0e74486da..ccd311fa7e 100644 --- a/src/applications/diffusion/application/PhabricatorDiffusionApplication.php +++ b/src/applications/diffusion/application/PhabricatorDiffusionApplication.php @@ -183,6 +183,9 @@ final class PhabricatorDiffusionApplication extends PhabricatorApplication { DiffusionCreateRepositoriesCapability::CAPABILITY => array( 'default' => PhabricatorPolicies::POLICY_ADMIN, ), + PhabricatorRepositoryIdentityEditViewCapability::CAPABILITY => array( + 'default' => PhabricatorPolicies::POLICY_USER, + ), ); } diff --git a/src/applications/repository/capability/PhabricatorRepositoryIdentityEditViewCapability.php b/src/applications/repository/capability/PhabricatorRepositoryIdentityEditViewCapability.php new file mode 100644 index 0000000000..9bb9b62ebc --- /dev/null +++ b/src/applications/repository/capability/PhabricatorRepositoryIdentityEditViewCapability.php @@ -0,0 +1,16 @@ +getApplication()->getPolicy( + PhabricatorRepositoryIdentityEditViewCapability::CAPABILITY); } protected function buildCustomEditFields($object) { diff --git a/src/applications/repository/storage/PhabricatorRepositoryIdentity.php b/src/applications/repository/storage/PhabricatorRepositoryIdentity.php index 74fbd06544..df19f302f6 100644 --- a/src/applications/repository/storage/PhabricatorRepositoryIdentity.php +++ b/src/applications/repository/storage/PhabricatorRepositoryIdentity.php @@ -142,7 +142,10 @@ final class PhabricatorRepositoryIdentity } public function getPolicy($capability) { - return PhabricatorPolicies::getMostOpenPolicy(); + $app = PhabricatorApplication::getByClass( + 'PhabricatorDiffusionApplication'); + return $app->getPolicy( + PhabricatorRepositoryIdentityEditViewCapability::CAPABILITY); } public function hasAutomaticCapability( From 005fea5a14f44ef44c72658d8b7eee92d50647c7 Mon Sep 17 00:00:00 2001 From: David Lawrence Date: Thu, 25 May 2023 15:42:26 -0400 Subject: [PATCH 65/93] Fix view policy inheritance on image transforms Summary: Inherit viewPolicy from original image in image transforms and warn about Profile transform making transformed images public. Details: https://hackerone.com/reports/1984060 https://github.com/mozilla-conduit/phabricator/commit/8358b435a99435a95e0dffbbb92f71dc1961bc7b Closes T15663 Test Plan: 1. Click {nav View Transforms} on an image file with restrictive view policy. 2. See (Image will be Public) warning on Profile transform. 3. Click on Workcard transform. 4. Go back to {nav View Transforms} page and visit the Workcard transformed file. 5. Check if its view policy matches the original file. Reviewers: O1 Blessed Committers, speck Reviewed By: O1 Blessed Committers, speck Subscribers: speck, tobiaswiese, valerio.bozzolan, Matthew, Cigaryno Maniphest Tasks: T15663 Differential Revision: https://we.phorge.it/D25462 Signed-off-by: Zero King --- .../files/transform/PhabricatorFileImageTransform.php | 6 +++++- .../files/transform/PhabricatorFileThumbnailTransform.php | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/applications/files/transform/PhabricatorFileImageTransform.php b/src/applications/files/transform/PhabricatorFileImageTransform.php index 468eae0e03..98ffcdd706 100644 --- a/src/applications/files/transform/PhabricatorFileImageTransform.php +++ b/src/applications/files/transform/PhabricatorFileImageTransform.php @@ -137,8 +137,12 @@ abstract class PhabricatorFileImageTransform extends PhabricatorFileTransform { protected function newFileFromData($data) { if ($this->file) { $name = $this->file->getName(); + $inherit_properties = array( + 'viewPolicy' => $this->file->getViewPolicy(), + ); } else { $name = 'default.png'; + $inherit_properties = array(); } $defaults = array( @@ -146,7 +150,7 @@ abstract class PhabricatorFileImageTransform extends PhabricatorFileTransform { 'name' => $this->getTransformKey().'-'.$name, ); - $properties = $this->getFileProperties() + $defaults; + $properties = $this->getFileProperties() + $inherit_properties + $defaults; return PhabricatorFile::newFromFileData($data, $properties); } diff --git a/src/applications/files/transform/PhabricatorFileThumbnailTransform.php b/src/applications/files/transform/PhabricatorFileThumbnailTransform.php index 2c61743078..6cf3914556 100644 --- a/src/applications/files/transform/PhabricatorFileThumbnailTransform.php +++ b/src/applications/files/transform/PhabricatorFileThumbnailTransform.php @@ -58,7 +58,7 @@ final class PhabricatorFileThumbnailTransform public function generateTransforms() { return array( id(new PhabricatorFileThumbnailTransform()) - ->setName(pht("Profile (400px \xC3\x97 400px)")) + ->setName(pht("Profile (400px \xC3\x97 400px) (Image will be Public)")) ->setKey(self::TRANSFORM_PROFILE) ->setDimensions(400, 400) ->setScaleUp(true), From 5d80b3fd88d1b98e6780609207bb93cf39cbbb2e Mon Sep 17 00:00:00 2001 From: Andre Klapper Date: Sat, 19 Aug 2023 10:06:34 +0200 Subject: [PATCH 66/93] Fix PHP 8.1 "strlen(null)" exception rendering PHUISegmentBar without a label Summary: `strlen()` was used in Phabricator to check if a generic value is a non-empty string. This behavior is deprecated since PHP 8.1. Phorge adopts `phutil_nonempty_string()` as a replacement. Note: this may highlight other absurd input values that might be worth correcting instead of just ignoring. If phutil_nonempty_string() throws an exception in your instance, report it to Phorge to evaluate and fix that specific corner case. ``` EXCEPTION: (RuntimeException) strlen(): Passing null to parameter #1 ($string) of type string is deprecated at [/src/error/PhutilErrorHandler.php:261] arcanist(head=master, ref.master=df6c315ace5f), phorge(head=master, ref.master=3cc5ee6a33df) #0 <#2> PhutilErrorHandler::handleError(integer, string, string, integer) called at [/src/view/phui/PHUISegmentBarView.php:33] ``` Closes T15622 Test Plan: After applying this change, page with the PHUISegmentBar without label renders as expected without an exception. For example, visit this page: /uiexample/view/PhabricatorAphrontBarUIExample/ Reviewers: O1 Blessed Committers, valerio.bozzolan Reviewed By: O1 Blessed Committers, valerio.bozzolan Subscribers: avivey, tobiaswiese, valerio.bozzolan, Matthew, Cigaryno Maniphest Tasks: T15622 Differential Revision: https://we.phorge.it/D25414 --- src/view/phui/PHUISegmentBarView.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/view/phui/PHUISegmentBarView.php b/src/view/phui/PHUISegmentBarView.php index 632c5327eb..8daa41c203 100644 --- a/src/view/phui/PHUISegmentBarView.php +++ b/src/view/phui/PHUISegmentBarView.php @@ -30,7 +30,7 @@ final class PHUISegmentBarView extends AphrontTagView { require_celerity_resource('phui-segment-bar-view-css'); $label = $this->label; - if (strlen($label)) { + if ($label !== null) { $label = phutil_tag( 'div', array( From 16d9cc12af45aeff9973c3c99495f7a45cdaf0c3 Mon Sep 17 00:00:00 2001 From: Zero King Date: Sat, 11 Nov 2023 15:45:21 +0800 Subject: [PATCH 67/93] Enforce viewable MIME types config on PDF documents Summary: Let instance admins decide whether to allow PDFs to be viewable as a Web page. See . MOZILLA: Instead of always allowing PDFs to be viewable in the web UI, [...] This checks that the PDF mimetype is viewable according to the system configuration. Ref Q83. Test Plan: 1. Set `files.viewable-mime-types` to exclude application/pdf. 2. Upload a pdf file. 3. See "No document engine can render the contents of this file." in web UI. Reviewers: O1 Blessed Committers, speck Reviewed By: O1 Blessed Committers, speck Subscribers: speck, tobiaswiese, valerio.bozzolan, Matthew, Cigaryno Differential Revision: https://we.phorge.it/D25464 --- .../config/PhabricatorFilesConfigOptions.php | 8 +++++--- .../document/PhabricatorPDFDocumentEngine.php | 16 +++++++++------- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/src/applications/files/config/PhabricatorFilesConfigOptions.php b/src/applications/files/config/PhabricatorFilesConfigOptions.php index 7ed96a412b..67d123e2cb 100644 --- a/src/applications/files/config/PhabricatorFilesConfigOptions.php +++ b/src/applications/files/config/PhabricatorFilesConfigOptions.php @@ -134,9 +134,11 @@ final class PhabricatorFilesConfigOptions ->setDescription( pht( "Configure which uploaded file types may be viewed directly ". - "in the browser. Other file types will be downloaded instead ". - "of displayed. This is mainly a usability consideration, since ". - "browsers tend to freak out when viewing very large binary files.". + "in the browser. Other types will be downloaded instead of ". + "displayed. This is a usability and security consideration, ". + "since browsers tend to freak out when viewing very large ". + "binary files, and some types may be vulnerable to XSS attacks ". + "when viewed in a browser.". "\n\n". "The keys in this map are viewable MIME types; the values are ". "the MIME types they are delivered as when they are viewed in ". diff --git a/src/applications/files/document/PhabricatorPDFDocumentEngine.php b/src/applications/files/document/PhabricatorPDFDocumentEngine.php index 1e85bd4ae5..bc6433290a 100644 --- a/src/applications/files/document/PhabricatorPDFDocumentEngine.php +++ b/src/applications/files/document/PhabricatorPDFDocumentEngine.php @@ -14,14 +14,16 @@ final class PhabricatorPDFDocumentEngine } protected function canRenderDocumentType(PhabricatorDocumentRef $ref) { - // Since we just render a link to the document anyway, we don't need to - // check anything fancy in config to see if the MIME type is actually - // viewable. + $viewable_types = PhabricatorEnv::getEnvConfig('files.viewable-mime-types'); + $viewable_types = array_keys($viewable_types); - return $ref->hasAnyMimeType( - array( - 'application/pdf', - )); + $pdf_types = array( + 'application/pdf', + ); + + return + $ref->hasAnyMimeType($viewable_types) && + $ref->hasAnyMimeType($pdf_types); } protected function newDocumentContent(PhabricatorDocumentRef $ref) { From 296ce3956b81718b1476b0185bc444d9bb82bee5 Mon Sep 17 00:00:00 2001 From: Waldir Pimenta Date: Sun, 12 Nov 2023 21:06:55 +0000 Subject: [PATCH 68/93] Fix loop in contribution docs Summary: The Contributor Introduction lists in the next steps the Contributing Code page; in its turn, the Contributing Code page links back to the Contributor Introduction page. This change fixes that infinite loop by adding an actual path forward, adding a link to the Developer Setup page in the Next Steps section of the Contributing Code page. Test Plan: Open the /book/contrib/article/contributing_code/ URL and confirm that the Developer Setup is included in the Next Steps section. Reviewers: O1 Blessed Committers, speck Reviewed By: O1 Blessed Committers, speck Subscribers: speck, tobiaswiese, valerio.bozzolan, Matthew, Cigaryno Differential Revision: https://we.phorge.it/D25465 --- src/docs/contributor/contributing_code.diviner | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/docs/contributor/contributing_code.diviner b/src/docs/contributor/contributing_code.diviner index c7bdec25c9..adc56aca1a 100644 --- a/src/docs/contributor/contributing_code.diviner +++ b/src/docs/contributor/contributing_code.diviner @@ -194,4 +194,6 @@ Next Steps Continue by: - - returning to the @{article:Contributor Introduction}. + - preparing your development environment as described in the + @{article:Developer Setup} + - returning to the @{article:Contributor Introduction} From 4535e8753c8be6e499ad2be9e9de9208fae048b0 Mon Sep 17 00:00:00 2001 From: Zero King Date: Mon, 13 Nov 2023 01:34:00 +0800 Subject: [PATCH 69/93] Fix typo in DiffusionLowLevelGitRefQuery Summary: $refs_types is undefined. Test Plan: None. PhabricatorRepositoryRefCursor::TYPE_REF is not used with DiffusionLowLevelGitRefQuery. Reviewers: O1 Blessed Committers, speck Reviewed By: O1 Blessed Committers, speck Subscribers: tobiaswiese, valerio.bozzolan, Matthew, Cigaryno Differential Revision: https://we.phorge.it/D25468 --- .../diffusion/query/lowlevel/DiffusionLowLevelGitRefQuery.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/applications/diffusion/query/lowlevel/DiffusionLowLevelGitRefQuery.php b/src/applications/diffusion/query/lowlevel/DiffusionLowLevelGitRefQuery.php index d11b658131..21c86e7435 100644 --- a/src/applications/diffusion/query/lowlevel/DiffusionLowLevelGitRefQuery.php +++ b/src/applications/diffusion/query/lowlevel/DiffusionLowLevelGitRefQuery.php @@ -27,7 +27,7 @@ final class DiffusionLowLevelGitRefQuery extends DiffusionLowLevelQuery { $with_branches = isset($ref_types[$type_branch]); $with_tags = isset($ref_types[$type_tag]); - $with_refs = isset($refs_types[$type_ref]); + $with_refs = isset($ref_types[$type_ref]); $repository = $this->getRepository(); From 486fc95b29fd1acbe890f5d04d6daa971033ad4e Mon Sep 17 00:00:00 2001 From: Zero King Date: Mon, 13 Nov 2023 01:55:01 +0800 Subject: [PATCH 70/93] Fix reentrancy guard in setDebugTimeLimit() Summary: $initialized is never initialized and onDebugTick() may be registered multiple times. Test Plan: None. The function is normally only called once. Reviewers: O1 Blessed Committers, speck Reviewed By: O1 Blessed Committers, speck Subscribers: tobiaswiese, valerio.bozzolan, Matthew, Cigaryno Differential Revision: https://we.phorge.it/D25469 --- support/startup/PhabricatorStartup.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/support/startup/PhabricatorStartup.php b/support/startup/PhabricatorStartup.php index b9d659d39b..b4a4314ac0 100644 --- a/support/startup/PhabricatorStartup.php +++ b/support/startup/PhabricatorStartup.php @@ -261,10 +261,11 @@ final class PhabricatorStartup { public static function setDebugTimeLimit($limit) { self::$debugTimeLimit = $limit; - static $initialized; + static $initialized = false; if (!$initialized) { declare(ticks=1); register_tick_function(array(__CLASS__, 'onDebugTick')); + $initialized = true; } } From 361fcd0cac368bf4d278907bfd00df46ef28eb29 Mon Sep 17 00:00:00 2001 From: Zero King Date: Mon, 13 Nov 2023 02:15:11 +0800 Subject: [PATCH 71/93] Initialize static variable to make linter happy Summary: Uninitialized variable defaults to 0 in this context. Make it explicit. Test Plan: None. No functional change. Reviewers: O1 Blessed Committers, speck Reviewed By: O1 Blessed Committers, speck Subscribers: tobiaswiese, valerio.bozzolan, Matthew, Cigaryno Differential Revision: https://we.phorge.it/D25470 --- src/applications/policy/filter/PhabricatorPolicyFilter.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/applications/policy/filter/PhabricatorPolicyFilter.php b/src/applications/policy/filter/PhabricatorPolicyFilter.php index d8f239e51a..3443d17156 100644 --- a/src/applications/policy/filter/PhabricatorPolicyFilter.php +++ b/src/applications/policy/filter/PhabricatorPolicyFilter.php @@ -461,7 +461,7 @@ final class PhabricatorPolicyFilter extends Phobject { // checks make it difficult to create cycles normally, so just do a // simple check here to limit damage. - static $depth; + static $depth = 0; $depth++; From aa8af1d79e8bfeb09e72d5e3b9330780e78b7aeb Mon Sep 17 00:00:00 2001 From: Zero King Date: Sun, 12 Nov 2023 16:21:57 +0800 Subject: [PATCH 72/93] Align logo image and text in site header Summary: Ref T15666. Center wordmark vertically to align with logo in site header. Test Plan: - Check alignment visually. - With browser DevTools, verify that wordmark is 44px tall. Reviewers: O1 Blessed Committers, valerio.bozzolan Reviewed By: O1 Blessed Committers, valerio.bozzolan Subscribers: tobiaswiese, valerio.bozzolan, Matthew, Cigaryno Maniphest Tasks: T15666 Differential Revision: https://we.phorge.it/D25467 --- resources/celerity/map.php | 12 ++++++------ webroot/rsrc/css/application/base/main-menu-view.css | 3 ++- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/resources/celerity/map.php b/resources/celerity/map.php index e40b474c14..fca4e57058 100644 --- a/resources/celerity/map.php +++ b/resources/celerity/map.php @@ -9,7 +9,7 @@ return array( 'names' => array( 'conpherence.pkg.css' => '76ed87e3', 'conpherence.pkg.js' => '020aebcf', - 'core.pkg.css' => '3c4918b0', + 'core.pkg.css' => 'c0bdb5b4', 'core.pkg.js' => '2eeda9e0', 'dark-console.pkg.js' => '187792c2', 'differential.pkg.css' => '2431def2', @@ -38,7 +38,7 @@ return array( 'rsrc/css/aphront/typeahead.css' => '8779483d', 'rsrc/css/application/almanac/almanac.css' => '2e050f4f', 'rsrc/css/application/auth/auth.css' => 'c2f23d74', - 'rsrc/css/application/base/main-menu-view.css' => '89fc16b6', + 'rsrc/css/application/base/main-menu-view.css' => '5d673247', 'rsrc/css/application/base/notification-menu.css' => '4df1ee30', 'rsrc/css/application/base/phui-theme.css' => '35883b37', 'rsrc/css/application/base/standard-page-view.css' => 'e08c7462', @@ -792,7 +792,7 @@ return array( 'phabricator-flag-css' => '2b77be8d', 'phabricator-keyboard-shortcut' => '1a844c06', 'phabricator-keyboard-shortcut-manager' => '81debc48', - 'phabricator-main-menu-view' => '89fc16b6', + 'phabricator-main-menu-view' => '5d673247', 'phabricator-nav-view-css' => '423f92cc', 'phabricator-notification' => 'a9b91e3f', 'phabricator-notification-css' => '30240bd2', @@ -1501,6 +1501,9 @@ return array( 'javelin-dom', 'phuix-dropdown-menu', ), + '5d673247' => array( + 'phui-theme-css', + ), '5d83623b' => array( 'javelin-dom', ), @@ -1689,9 +1692,6 @@ return array( 'javelin-stratcom', 'javelin-install', ), - '89fc16b6' => array( - 'phui-theme-css', - ), '8ac32fd9' => array( 'javelin-behavior', 'javelin-stratcom', diff --git a/webroot/rsrc/css/application/base/main-menu-view.css b/webroot/rsrc/css/application/base/main-menu-view.css index 8c5000247a..6aace18b44 100644 --- a/webroot/rsrc/css/application/base/main-menu-view.css +++ b/webroot/rsrc/css/application/base/main-menu-view.css @@ -70,7 +70,8 @@ float: left; color: #fff; font-size: 18px; - margin: 9px 4px 9px 6px; + line-height: 22px; + margin: 11px 4px 11px 6px; padding-right: 8px; max-width: 175px; overflow: hidden; From 282e37aaf68257251712a1bf7533b9cc85d16262 Mon Sep 17 00:00:00 2001 From: Andre Klapper Date: Mon, 13 Nov 2023 14:03:55 +0100 Subject: [PATCH 73/93] Do not expose Contact Numbers settings panel when no SMS support configured Summary: It's useless without SMS support and only exposed to the user themselves. Closes T15486 Test Plan: Before and after applying this patch, * Try to access the list of your contact numbers at `/settings/panel/contact/` * Try to access an existing, previously created contact number at `/auth/contact/1/` * Try to add a contact number at `/auth/contact/edit/` * Go to e.g. `/settings/panel/datetime` and check the "Authentication" section in the left sidebar for {nav icon=hashtag, name=Contact Numbers} Reviewers: O1 Blessed Committers, speck Reviewed By: O1 Blessed Committers, speck Subscribers: speck, tobiaswiese, valerio.bozzolan, Matthew, Cigaryno Maniphest Tasks: T15486 Differential Revision: https://we.phorge.it/D25452 --- ...atorAuthContactNumberDisableController.php | 23 +++++++++++-------- ...ricatorAuthContactNumberEditController.php | 11 ++++++--- ...atorAuthContactNumberPrimaryController.php | 23 +++++++++++-------- ...ricatorAuthContactNumberTestController.php | 23 +++++++++++-------- ...ricatorAuthContactNumberViewController.php | 13 +++++++---- .../auth/factor/PhabricatorSMSAuthFactor.php | 2 +- ...PhabricatorContactNumbersSettingsPanel.php | 12 ++++++++++ 7 files changed, 68 insertions(+), 39 deletions(-) diff --git a/src/applications/auth/controller/contact/PhabricatorAuthContactNumberDisableController.php b/src/applications/auth/controller/contact/PhabricatorAuthContactNumberDisableController.php index a525e7b930..28b7e69593 100644 --- a/src/applications/auth/controller/contact/PhabricatorAuthContactNumberDisableController.php +++ b/src/applications/auth/controller/contact/PhabricatorAuthContactNumberDisableController.php @@ -7,16 +7,19 @@ final class PhabricatorAuthContactNumberDisableController $viewer = $request->getViewer(); $id = $request->getURIData('id'); - $number = id(new PhabricatorAuthContactNumberQuery()) - ->setViewer($viewer) - ->withIDs(array($id)) - ->requireCapabilities( - array( - PhabricatorPolicyCapability::CAN_VIEW, - PhabricatorPolicyCapability::CAN_EDIT, - )) - ->executeOne(); - if (!$number) { + $sms_auth_factor = new PhabricatorSMSAuthFactor(); + if ($sms_auth_factor->isSMSMailerConfigured()) { + $number = id(new PhabricatorAuthContactNumberQuery()) + ->setViewer($viewer) + ->withIDs(array($id)) + ->requireCapabilities( + array( + PhabricatorPolicyCapability::CAN_VIEW, + PhabricatorPolicyCapability::CAN_EDIT, + )) + ->executeOne(); + } + if (!isset($number) || !$number) { return new Aphront404Response(); } diff --git a/src/applications/auth/controller/contact/PhabricatorAuthContactNumberEditController.php b/src/applications/auth/controller/contact/PhabricatorAuthContactNumberEditController.php index 95764496da..c012ca3581 100644 --- a/src/applications/auth/controller/contact/PhabricatorAuthContactNumberEditController.php +++ b/src/applications/auth/controller/contact/PhabricatorAuthContactNumberEditController.php @@ -4,9 +4,14 @@ final class PhabricatorAuthContactNumberEditController extends PhabricatorAuthContactNumberController { public function handleRequest(AphrontRequest $request) { - return id(new PhabricatorAuthContactNumberEditEngine()) - ->setController($this) - ->buildResponse(); + $sms_auth_factor = new PhabricatorSMSAuthFactor(); + if ($sms_auth_factor->isSMSMailerConfigured()) { + return id(new PhabricatorAuthContactNumberEditEngine()) + ->setController($this) + ->buildResponse(); + } else { + return new Aphront404Response(); + } } } diff --git a/src/applications/auth/controller/contact/PhabricatorAuthContactNumberPrimaryController.php b/src/applications/auth/controller/contact/PhabricatorAuthContactNumberPrimaryController.php index cad1bbf3fc..63ba5ad883 100644 --- a/src/applications/auth/controller/contact/PhabricatorAuthContactNumberPrimaryController.php +++ b/src/applications/auth/controller/contact/PhabricatorAuthContactNumberPrimaryController.php @@ -7,16 +7,19 @@ final class PhabricatorAuthContactNumberPrimaryController $viewer = $request->getViewer(); $id = $request->getURIData('id'); - $number = id(new PhabricatorAuthContactNumberQuery()) - ->setViewer($viewer) - ->withIDs(array($id)) - ->requireCapabilities( - array( - PhabricatorPolicyCapability::CAN_VIEW, - PhabricatorPolicyCapability::CAN_EDIT, - )) - ->executeOne(); - if (!$number) { + $sms_auth_factor = new PhabricatorSMSAuthFactor(); + if ($sms_auth_factor->isSMSMailerConfigured()) { + $number = id(new PhabricatorAuthContactNumberQuery()) + ->setViewer($viewer) + ->withIDs(array($id)) + ->requireCapabilities( + array( + PhabricatorPolicyCapability::CAN_VIEW, + PhabricatorPolicyCapability::CAN_EDIT, + )) + ->executeOne(); + } + if (!isset($number) || !$number) { return new Aphront404Response(); } diff --git a/src/applications/auth/controller/contact/PhabricatorAuthContactNumberTestController.php b/src/applications/auth/controller/contact/PhabricatorAuthContactNumberTestController.php index f8c8b013bf..a991c34a6d 100644 --- a/src/applications/auth/controller/contact/PhabricatorAuthContactNumberTestController.php +++ b/src/applications/auth/controller/contact/PhabricatorAuthContactNumberTestController.php @@ -7,16 +7,19 @@ final class PhabricatorAuthContactNumberTestController $viewer = $request->getViewer(); $id = $request->getURIData('id'); - $number = id(new PhabricatorAuthContactNumberQuery()) - ->setViewer($viewer) - ->withIDs(array($id)) - ->requireCapabilities( - array( - PhabricatorPolicyCapability::CAN_VIEW, - PhabricatorPolicyCapability::CAN_EDIT, - )) - ->executeOne(); - if (!$number) { + $sms_auth_factor = new PhabricatorSMSAuthFactor(); + if ($sms_auth_factor->isSMSMailerConfigured()) { + $number = id(new PhabricatorAuthContactNumberQuery()) + ->setViewer($viewer) + ->withIDs(array($id)) + ->requireCapabilities( + array( + PhabricatorPolicyCapability::CAN_VIEW, + PhabricatorPolicyCapability::CAN_EDIT, + )) + ->executeOne(); + } + if (!isset($number) || !$number) { return new Aphront404Response(); } diff --git a/src/applications/auth/controller/contact/PhabricatorAuthContactNumberViewController.php b/src/applications/auth/controller/contact/PhabricatorAuthContactNumberViewController.php index 027d288dbc..75e4b8e3b7 100644 --- a/src/applications/auth/controller/contact/PhabricatorAuthContactNumberViewController.php +++ b/src/applications/auth/controller/contact/PhabricatorAuthContactNumberViewController.php @@ -6,11 +6,14 @@ final class PhabricatorAuthContactNumberViewController public function handleRequest(AphrontRequest $request) { $viewer = $this->getViewer(); - $number = id(new PhabricatorAuthContactNumberQuery()) - ->setViewer($viewer) - ->withIDs(array($request->getURIData('id'))) - ->executeOne(); - if (!$number) { + $sms_auth_factor = new PhabricatorSMSAuthFactor(); + if ($sms_auth_factor->isSMSMailerConfigured()) { + $number = id(new PhabricatorAuthContactNumberQuery()) + ->setViewer($viewer) + ->withIDs(array($request->getURIData('id'))) + ->executeOne(); + } + if (!isset($number) || !$number) { return new Aphront404Response(); } diff --git a/src/applications/auth/factor/PhabricatorSMSAuthFactor.php b/src/applications/auth/factor/PhabricatorSMSAuthFactor.php index 33f640e692..2350855859 100644 --- a/src/applications/auth/factor/PhabricatorSMSAuthFactor.php +++ b/src/applications/auth/factor/PhabricatorSMSAuthFactor.php @@ -334,7 +334,7 @@ final class PhabricatorSMSAuthFactor return $value; } - private function isSMSMailerConfigured() { + public function isSMSMailerConfigured() { $mailers = PhabricatorMetaMTAMail::newMailers( array( 'outbound' => true, diff --git a/src/applications/settings/panel/PhabricatorContactNumbersSettingsPanel.php b/src/applications/settings/panel/PhabricatorContactNumbersSettingsPanel.php index 7056fd02de..60a2064546 100644 --- a/src/applications/settings/panel/PhabricatorContactNumbersSettingsPanel.php +++ b/src/applications/settings/panel/PhabricatorContactNumbersSettingsPanel.php @@ -19,6 +19,18 @@ final class PhabricatorContactNumbersSettingsPanel return PhabricatorSettingsAuthenticationPanelGroup::PANELGROUPKEY; } + /** + * Whether to display "Contact Numbers" panel in users' Personal + * Settings by checking if global SMS support is configured + */ + public function isUserPanel() { + $sms_auth_factor = new PhabricatorSMSAuthFactor(); + if ($sms_auth_factor->isSMSMailerConfigured()) { + return true; + } + return false; + } + public function isMultiFactorEnrollmentPanel() { return true; } From 775d141fe6bf4ce1f7e596dd856962f054f16d1a Mon Sep 17 00:00:00 2001 From: Valerio Bozzolan Date: Wed, 15 Nov 2023 13:56:04 +0100 Subject: [PATCH 74/93] Audit Feed: less verbose when the author is the committer Summary: If the author and the committer are the same person, do not show them twice. From: UsernameFoo committed : (authored by UsernameFoo). To: UsernameFoo committed : This only affects the feed. | Before | After | |-----------|-----------| | {F342758} | {F342764} | Closes T15528 Test Plan: Do some mixed commits and visit /feed/query/all/. No nuclear implosions. Reviewers: O1 Blessed Committers, speck Reviewed By: O1 Blessed Committers, speck Subscribers: speck, tobiaswiese, Matthew, Cigaryno Maniphest Tasks: T15528 Differential Revision: https://we.phorge.it/D25421 --- .../audit/storage/PhabricatorAuditTransaction.php | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/applications/audit/storage/PhabricatorAuditTransaction.php b/src/applications/audit/storage/PhabricatorAuditTransaction.php index e6c1062092..8e49d99520 100644 --- a/src/applications/audit/storage/PhabricatorAuditTransaction.php +++ b/src/applications/audit/storage/PhabricatorAuditTransaction.php @@ -338,7 +338,17 @@ final class PhabricatorAuditTransaction $author = null; } - if ($author) { + // Show both Author and Committer only if they are different. + $show_both = $author && $committer; + if ($show_both) { + if ($new['authorPHID']) { + $show_both = $new['authorPHID'] !== $new['committerPHID']; + } else if (phutil_nonempty_string($new['authorName'])) { + $show_both = $new['authorName'] !== $new['committerName']; + } + } + + if ($show_both) { $title = pht( '%s committed %s (authored by %s).', $committer, From f42dd5819e98c4ff1adc73c22b5f79b42c475538 Mon Sep 17 00:00:00 2001 From: Andre Klapper Date: Thu, 16 Nov 2023 10:41:43 +0100 Subject: [PATCH 75/93] Fix possible array to string conversion renaming Pholio Mockup image Summary: Premising that the `$old` and `$new` variables are 1-element arrays defined as PHID=>title, this can cause `renderValue()` repeatedly fail when passing an array instead of its value. Thus pass `head($old)` instead, to get the first value - that is the only one, even if you rename multiple images (since this Transaction is about a single Mockup image). Closes T15646 Test Plan: * Have `phd` running * Create a Pholio mockup with at least one image Edit the Pholio mockup and: 1. rename the Titles of an image 2. rename a single Image 3. rename no image No nuclear implosions. You still see a lovely Feed mentioning each rename. Reviewers: O1 Blessed Committers, valerio.bozzolan Reviewed By: O1 Blessed Committers, valerio.bozzolan Subscribers: speck, tobiaswiese, valerio.bozzolan, Matthew, Cigaryno Maniphest Tasks: T15646 Differential Revision: https://we.phorge.it/D25441 --- .../pholio/xaction/PholioImageNameTransaction.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/applications/pholio/xaction/PholioImageNameTransaction.php b/src/applications/pholio/xaction/PholioImageNameTransaction.php index 33b01903ee..f4705a98fc 100644 --- a/src/applications/pholio/xaction/PholioImageNameTransaction.php +++ b/src/applications/pholio/xaction/PholioImageNameTransaction.php @@ -31,8 +31,8 @@ final class PholioImageNameTransaction '%s renamed an image (%s) from %s to %s.', $this->renderAuthor(), $this->renderHandle(key($new)), - $this->renderValue($old), - $this->renderValue($new)); + $this->renderValue((string)head($old)), + $this->renderValue((string)head($new))); } public function getTitleForFeed() { From 76ed0c7ff7be9d87dd32f14bf9ddb7379261a410 Mon Sep 17 00:00:00 2001 From: Andre Klapper Date: Fri, 10 Nov 2023 12:56:43 +0100 Subject: [PATCH 76/93] Disallow webcrawlers to follow Paste line number anchor links Summary: Paste provides line anchor links in every single line of a paste. If webcrawlers follow these links, they index the very same Paste again. Thus disallow in robots.txt to reduce unneeded traffic and indexing time. Closes T15662 Test Plan: Go to `/robots.txt` in the web browser. Cross fingers that more webcrawlers abide by RFC 9309. Reviewers: O1 Blessed Committers, valerio.bozzolan Reviewed By: O1 Blessed Committers, valerio.bozzolan Subscribers: tobiaswiese, valerio.bozzolan, Matthew, Cigaryno Maniphest Tasks: T15662 Differential Revision: https://we.phorge.it/D25461 --- .../robots/PhabricatorRobotsPlatformController.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/applications/system/controller/robots/PhabricatorRobotsPlatformController.php b/src/applications/system/controller/robots/PhabricatorRobotsPlatformController.php index b4a3c4fa37..82028918d7 100644 --- a/src/applications/system/controller/robots/PhabricatorRobotsPlatformController.php +++ b/src/applications/system/controller/robots/PhabricatorRobotsPlatformController.php @@ -19,6 +19,13 @@ final class PhabricatorRobotsPlatformController $out[] = 'Disallow: /diffusion/'; $out[] = 'Disallow: /source/'; + // See T15662. Prevent indexing line anchor links in Pastes. Per RFC 9309 + // section 2.2.3, percentage-encode "$" to avoid interpretation as end of + // match pattern. However, crawlers may not abide by it but follow the + // original standard at https://www.robotstxt.org/orig.html with no mention + // how to interpret characters like "$" and thus entirely ignore this rule. + $out[] = 'Disallow: /P*%24*'; + // Add a small crawl delay (number of seconds between requests) for spiders // which respect it. The intent here is to prevent spiders from affecting // performance for users. The possible cost is slower indexing, but that From 05f4d5071fdca02123bd1ff4c0935b847c7f9963 Mon Sep 17 00:00:00 2001 From: Andre Klapper Date: Fri, 17 Nov 2023 08:44:19 +0100 Subject: [PATCH 77/93] Disallow webcrawlers to index Diffusion commits Summary: Phorge already sets `Disallow: /diffusion/` and `Disallow: /source/`. Thus consequently also disallow accessing specific commits via `/r*`. See https://secure.phabricator.com/T4610 for previous discussions. Closes T15670 Test Plan: Go to `/robots.txt` in the web browser. Cross fingers that more webcrawlers abide by RFC 9309. Reviewers: O1 Blessed Committers, speck Reviewed By: O1 Blessed Committers, speck Subscribers: tobiaswiese, valerio.bozzolan, Matthew, Cigaryno Maniphest Tasks: T15670 Differential Revision: https://we.phorge.it/D25474 --- .../controller/robots/PhabricatorRobotsPlatformController.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/applications/system/controller/robots/PhabricatorRobotsPlatformController.php b/src/applications/system/controller/robots/PhabricatorRobotsPlatformController.php index 82028918d7..7151f2e4aa 100644 --- a/src/applications/system/controller/robots/PhabricatorRobotsPlatformController.php +++ b/src/applications/system/controller/robots/PhabricatorRobotsPlatformController.php @@ -18,6 +18,8 @@ final class PhabricatorRobotsPlatformController $out[] = 'User-Agent: *'; $out[] = 'Disallow: /diffusion/'; $out[] = 'Disallow: /source/'; + // See T15670. Also prevent directly accessing commits in Diffusion. + $out[] = 'Disallow: /r*'; // See T15662. Prevent indexing line anchor links in Pastes. Per RFC 9309 // section 2.2.3, percentage-encode "$" to avoid interpretation as end of From a741f5d65c103d114b82cf0f70563334d1c3eb4c Mon Sep 17 00:00:00 2001 From: Waldir Pimenta Date: Sat, 18 Nov 2023 22:13:49 +0000 Subject: [PATCH 78/93] Change some instances of "phabricator" to "phorge" Summary: Just a small set of replacements in locations that seem innocuous (user-facing messages, documentation, etc.) Ref T15006 Test Plan: Nothing should change in terms of behavior. The places where these changes were made should now say "phorge". Example tests: - Manage a single User and click on Delete User and see the popup - Run a test email and check the output ./bin/mail send-test --to username - Visit /maniphest/, shift+click on at least 1 Task, click on Bulk Edit Selected, Continue, see the popup - See the mentioned documentation with your big eyes. Eyes do not explode \o/ Reviewers: O1 Blessed Committers, valerio.bozzolan Reviewed By: O1 Blessed Committers, valerio.bozzolan Subscribers: tobiaswiese, valerio.bozzolan, Matthew, Cigaryno Maniphest Tasks: T15006 Differential Revision: https://we.phorge.it/D25473 --- conf/aphlict/README | 2 +- scripts/init/lib.php | 2 +- .../config/option/PhabricatorConfigOption.php | 2 +- .../PhabricatorMailManagementReceiveTestWorkflow.php | 3 ++- .../PhabricatorMailManagementSendTestWorkflow.php | 3 ++- .../controller/PhabricatorPeopleDeleteController.php | 9 ++++++--- .../bulk/PhabricatorEditEngineBulkJobType.php | 4 ++-- .../events/PhabricatorAutoEventListener.php | 2 +- 8 files changed, 16 insertions(+), 11 deletions(-) diff --git a/conf/aphlict/README b/conf/aphlict/README index 2786ea5658..0704bf6068 100644 --- a/conf/aphlict/README +++ b/conf/aphlict/README @@ -8,7 +8,7 @@ be read by default. To specify a path when starting Aphlict, use the `--config` flag: - phabricator/ $ ./bin/aphlict start --config path/to/config.json + phorge/ $ ./bin/aphlict start --config path/to/config.json Specifying a configuration file explicitly overrides default configuration. diff --git a/scripts/init/lib.php b/scripts/init/lib.php index 4c544da9d0..a12c394f3b 100644 --- a/scripts/init/lib.php +++ b/scripts/init/lib.php @@ -13,7 +13,7 @@ function init_phabricator_script(array $options) { if (!$ok) { echo 'FATAL ERROR: Unable to load the "Arcanist" library. '. - 'Put "arcanist/" next to "phabricator/" on disk.'; + 'Put "arcanist/" next to "phorge/" on disk.'; echo "\n"; exit(1); diff --git a/src/applications/config/option/PhabricatorConfigOption.php b/src/applications/config/option/PhabricatorConfigOption.php index 6b38bbb6d6..ee79005d5d 100644 --- a/src/applications/config/option/PhabricatorConfigOption.php +++ b/src/applications/config/option/PhabricatorConfigOption.php @@ -77,7 +77,7 @@ final class PhabricatorConfigOption 'This configuration is locked and can not be edited from the web '. 'interface. Use %s in %s to edit it.', phutil_tag('tt', array(), './bin/config'), - phutil_tag('tt', array(), 'phabricator/')); + phutil_tag('tt', array(), PlatformSymbols::getPlatformServerPath())); } public function addExample($value, $description) { diff --git a/src/applications/metamta/management/PhabricatorMailManagementReceiveTestWorkflow.php b/src/applications/metamta/management/PhabricatorMailManagementReceiveTestWorkflow.php index 73917a2d84..a3c556e6ac 100644 --- a/src/applications/metamta/management/PhabricatorMailManagementReceiveTestWorkflow.php +++ b/src/applications/metamta/management/PhabricatorMailManagementReceiveTestWorkflow.php @@ -181,8 +181,9 @@ final class PhabricatorMailManagementReceiveTestWorkflow $received->processReceivedMail(); $console->writeErr( - "%s\n\n phabricator/ $ ./bin/mail show-inbound --id %d\n\n", + "%s\n\n %s $ ./bin/mail show-inbound --id %d\n\n", pht('Mail received! You can view details by running this command:'), + PlatformSymbols::getPlatformServerPath(), $received->getID()); } diff --git a/src/applications/metamta/management/PhabricatorMailManagementSendTestWorkflow.php b/src/applications/metamta/management/PhabricatorMailManagementSendTestWorkflow.php index 6ea2c9de5a..54c7ff53f6 100644 --- a/src/applications/metamta/management/PhabricatorMailManagementSendTestWorkflow.php +++ b/src/applications/metamta/management/PhabricatorMailManagementSendTestWorkflow.php @@ -225,8 +225,9 @@ final class PhabricatorMailManagementSendTestWorkflow $mail->save(); $console->writeErr( - "%s\n\n phabricator/ $ ./bin/mail show-outbound --id %d\n\n", + "%s\n\n %s $ ./bin/mail show-outbound --id %d\n\n", pht('Mail sent! You can view details by running this command:'), + PlatformSymbols::getPlatformServerPath(), $mail->getID()); } diff --git a/src/applications/people/controller/PhabricatorPeopleDeleteController.php b/src/applications/people/controller/PhabricatorPeopleDeleteController.php index 8e6ac91da7..2f45b40d31 100644 --- a/src/applications/people/controller/PhabricatorPeopleDeleteController.php +++ b/src/applications/people/controller/PhabricatorPeopleDeleteController.php @@ -27,9 +27,12 @@ final class PhabricatorPeopleDeleteController 'To permanently destroy this user, run this command from the '. 'command line:')) ->appendCommand( - csprintf( - 'phabricator/ $ ./bin/remove destroy %R', - $user->getMonogram())) + hsprintf( + '%s $ %s', + PlatformSymbols::getPlatformServerPath(), + csprintf( + './bin/remove destroy %R', + $user->getMonogram()))) ->appendParagraph( pht( 'Unless you have a very good reason to delete this user, consider '. diff --git a/src/applications/transactions/bulk/PhabricatorEditEngineBulkJobType.php b/src/applications/transactions/bulk/PhabricatorEditEngineBulkJobType.php index 758e7f3439..811b4e1565 100644 --- a/src/applications/transactions/bulk/PhabricatorEditEngineBulkJobType.php +++ b/src/applications/transactions/bulk/PhabricatorEditEngineBulkJobType.php @@ -31,9 +31,9 @@ final class PhabricatorEditEngineBulkJobType $parts[] = pht('To silence this edit, run this command:'); $command = csprintf( - 'phabricator/ $ ./bin/bulk make-silent --id %R', + '%s $ ./bin/bulk make-silent --id %R', + PlatformSymbols::getPlatformServerPath(), $job->getID()); - $command = (string)$command; $parts[] = phutil_tag('tt', array(), $command); diff --git a/src/infrastructure/events/PhabricatorAutoEventListener.php b/src/infrastructure/events/PhabricatorAutoEventListener.php index 0ed76b3390..a8419f6865 100644 --- a/src/infrastructure/events/PhabricatorAutoEventListener.php +++ b/src/infrastructure/events/PhabricatorAutoEventListener.php @@ -10,6 +10,6 @@ * * All concrete subclasses of this class are automatically registered at * startup. This allows it to be used with custom one-offs that can be dropped - * into `phabricator/src/extensions/`. + * into `phorge/src/extensions/`. */ abstract class PhabricatorAutoEventListener extends PhabricatorEventListener {} From 1b49165ddd16e7a5c6542748b06ea89729fb07a1 Mon Sep 17 00:00:00 2001 From: Matthew Bowker Date: Tue, 21 Nov 2023 11:17:19 -0700 Subject: [PATCH 79/93] Show more in Application Detail and List view Summary: Update the Application Detail view and List View to show a unified set of Badges (Deprecated, etc.), show PHIDs and Monograms on the Application Detail view, allow Applications to register Monograms. Example of the page /applications/view/PhabricatorDiffusionApplication/: {F393393} T15568 Test Plan: 1. Visit /applications/ and see Deprecated badges etc. 2. Visit various Configure buttons from that list and see Monograms, Badges, PHIDs etc. 3. Enjoy screenshots in the comments of this Diff Reviewers: O1 Blessed Committers, valerio.bozzolan, avivey, speck Reviewed By: O1 Blessed Committers, valerio.bozzolan, avivey, speck Subscribers: avivey, speck, tobiaswiese, valerio.bozzolan, Cigaryno Differential Revision: https://we.phorge.it/D25362 --- .../base/PhabricatorApplication.php | 15 +++++++ .../PhabricatorCalendarApplication.php | 4 ++ .../PhabricatorChatLogApplication.php | 8 +++- .../PhabricatorConpherenceApplication.php | 4 ++ .../PhabricatorCountdownApplication.php | 4 ++ .../PhabricatorDashboardApplication.php | 4 ++ .../PhabricatorDifferentialApplication.php | 4 ++ .../PhabricatorDiffusionApplication.php | 5 +++ .../PhabricatorFilesApplication.php | 4 ++ .../PhabricatorFundApplication.php | 4 ++ .../PhabricatorHarbormasterApplication.php | 4 ++ .../PhabricatorHeraldApplication.php | 4 ++ .../PhabricatorLegalpadApplication.php | 4 ++ .../PhabricatorManiphestApplication.php | 4 ++ ...ricatorApplicationDetailViewController.php | 45 +++++++++++++++++++ .../meta/query/PhabricatorAppSearchEngine.php | 18 ++++++-- .../PhabricatorOwnersApplication.php | 4 ++ .../PhabricatorPassphraseApplication.php | 4 ++ .../PhabricatorPasteApplication.php | 4 ++ .../PhabricatorPhameApplication.php | 4 ++ .../phid/type/PhabricatorPHIDType.php | 24 ++++++++++ .../PhabricatorPholioApplication.php | 4 ++ .../PhabricatorPhurlApplication.php | 4 ++ .../PhabricatorPonderApplication.php | 4 ++ .../PhabricatorSlowvoteApplication.php | 4 ++ .../PhabricatorSpacesApplication.php | 4 ++ 26 files changed, 189 insertions(+), 6 deletions(-) diff --git a/src/applications/base/PhabricatorApplication.php b/src/applications/base/PhabricatorApplication.php index 9e1ea7d5ba..67294db263 100644 --- a/src/applications/base/PhabricatorApplication.php +++ b/src/applications/base/PhabricatorApplication.php @@ -61,6 +61,21 @@ abstract class PhabricatorApplication return pht('%s Application', $this->getName()); } + /** + * Extensions are allowed to register multi-character monograms. + * The name "Monogram" is actually a bit of a misnomer, + * but we're keeping it due to the history. + * + * @return array + */ + public function getMonograms() { + return array(); + } + + public function isDeprecated() { + return false; + } + final public function isInstalled() { if (!$this->canUninstall()) { return true; diff --git a/src/applications/calendar/application/PhabricatorCalendarApplication.php b/src/applications/calendar/application/PhabricatorCalendarApplication.php index fa534280a0..c9ff3ac9d3 100644 --- a/src/applications/calendar/application/PhabricatorCalendarApplication.php +++ b/src/applications/calendar/application/PhabricatorCalendarApplication.php @@ -28,6 +28,10 @@ final class PhabricatorCalendarApplication extends PhabricatorApplication { return "\xE2\x8C\xA8"; } + public function getMonograms() { + return array('E'); + } + public function getApplicationGroup() { return self::GROUP_UTILITIES; } diff --git a/src/applications/chatlog/application/PhabricatorChatLogApplication.php b/src/applications/chatlog/application/PhabricatorChatLogApplication.php index 912ddd9b6b..ab5eb1960f 100644 --- a/src/applications/chatlog/application/PhabricatorChatLogApplication.php +++ b/src/applications/chatlog/application/PhabricatorChatLogApplication.php @@ -11,7 +11,7 @@ final class PhabricatorChatLogApplication extends PhabricatorApplication { } public function getShortDescription() { - return pht('(Deprecated)'); + return pht('IRC Logs'); } public function getIcon() { @@ -22,6 +22,10 @@ final class PhabricatorChatLogApplication extends PhabricatorApplication { return true; } + public function isDeprecated() { + return true; + } + public function getTitleGlyph() { return "\xE0\xBC\x84"; } @@ -30,7 +34,7 @@ final class PhabricatorChatLogApplication extends PhabricatorApplication { return self::GROUP_UTILITIES; } - public function getRoutes() { + public function getRoutes() { return array( '/chatlog/' => array( '' => 'PhabricatorChatLogChannelListController', diff --git a/src/applications/conpherence/application/PhabricatorConpherenceApplication.php b/src/applications/conpherence/application/PhabricatorConpherenceApplication.php index a0c21bd33a..f3118be9bf 100644 --- a/src/applications/conpherence/application/PhabricatorConpherenceApplication.php +++ b/src/applications/conpherence/application/PhabricatorConpherenceApplication.php @@ -28,6 +28,10 @@ final class PhabricatorConpherenceApplication extends PhabricatorApplication { ); } + public function getMonograms() { + return array('Z'); + } + public function getRoutes() { return array( '/Z(?P[1-9]\d*)' diff --git a/src/applications/countdown/application/PhabricatorCountdownApplication.php b/src/applications/countdown/application/PhabricatorCountdownApplication.php index e205ba64c3..5f06e6ef9f 100644 --- a/src/applications/countdown/application/PhabricatorCountdownApplication.php +++ b/src/applications/countdown/application/PhabricatorCountdownApplication.php @@ -36,6 +36,10 @@ final class PhabricatorCountdownApplication extends PhabricatorApplication { ); } + public function getMonograms() { + return array('C'); + } + public function getRoutes() { return array( '/C(?P[1-9]\d*)' => 'PhabricatorCountdownViewController', diff --git a/src/applications/dashboard/application/PhabricatorDashboardApplication.php b/src/applications/dashboard/application/PhabricatorDashboardApplication.php index 3cdb932514..aeb2f43195 100644 --- a/src/applications/dashboard/application/PhabricatorDashboardApplication.php +++ b/src/applications/dashboard/application/PhabricatorDashboardApplication.php @@ -30,6 +30,10 @@ final class PhabricatorDashboardApplication extends PhabricatorApplication { return 0.160; } + public function getMonograms() { + return array('W'); + } + public function getRoutes() { $menu_rules = $this->getProfileMenuRouting( 'PhabricatorDashboardPortalViewController'); diff --git a/src/applications/differential/application/PhabricatorDifferentialApplication.php b/src/applications/differential/application/PhabricatorDifferentialApplication.php index 5980f738b0..16b3193dac 100644 --- a/src/applications/differential/application/PhabricatorDifferentialApplication.php +++ b/src/applications/differential/application/PhabricatorDifferentialApplication.php @@ -42,6 +42,10 @@ final class PhabricatorDifferentialApplication 'engineers to review, discuss and approve changes to software.'); } + public function getMonograms() { + return array('D'); + } + public function getRoutes() { return array( '/D(?P[1-9]\d*)' => array( diff --git a/src/applications/diffusion/application/PhabricatorDiffusionApplication.php b/src/applications/diffusion/application/PhabricatorDiffusionApplication.php index ccd311fa7e..a2b9f81aee 100644 --- a/src/applications/diffusion/application/PhabricatorDiffusionApplication.php +++ b/src/applications/diffusion/application/PhabricatorDiffusionApplication.php @@ -44,6 +44,11 @@ final class PhabricatorDiffusionApplication extends PhabricatorApplication { ); } + public function getMonograms() { + // This is a special case, as r and R mean different things. + return array('r', 'R'); + } + public function getRoutes() { $repository_routes = array( '/' => array( diff --git a/src/applications/files/application/PhabricatorFilesApplication.php b/src/applications/files/application/PhabricatorFilesApplication.php index e246d4c90c..4014a6ce62 100644 --- a/src/applications/files/application/PhabricatorFilesApplication.php +++ b/src/applications/files/application/PhabricatorFilesApplication.php @@ -67,6 +67,10 @@ final class PhabricatorFilesApplication extends PhabricatorApplication { ); } + public function getMonograms() { + return array('F'); + } + public function getRoutes() { return array( '/F(?P[1-9]\d*)(?:\$(?P\d+(?:-\d+)?))?' diff --git a/src/applications/fund/application/PhabricatorFundApplication.php b/src/applications/fund/application/PhabricatorFundApplication.php index 58ce4f8922..5e2d33c1a4 100644 --- a/src/applications/fund/application/PhabricatorFundApplication.php +++ b/src/applications/fund/application/PhabricatorFundApplication.php @@ -36,6 +36,10 @@ final class PhabricatorFundApplication extends PhabricatorApplication { ); } + public function getMonograms() { + return array('I'); + } + public function getRoutes() { return array( '/I(?P[1-9]\d*)' => 'FundInitiativeViewController', diff --git a/src/applications/harbormaster/application/PhabricatorHarbormasterApplication.php b/src/applications/harbormaster/application/PhabricatorHarbormasterApplication.php index 6c499bf63a..7de2a658c2 100644 --- a/src/applications/harbormaster/application/PhabricatorHarbormasterApplication.php +++ b/src/applications/harbormaster/application/PhabricatorHarbormasterApplication.php @@ -51,6 +51,10 @@ final class PhabricatorHarbormasterApplication extends PhabricatorApplication { ); } + public function getMonograms() { + return array('B'); + } + public function getRoutes() { return array( '/B(?P[1-9]\d*)' => 'HarbormasterBuildableViewController', diff --git a/src/applications/herald/application/PhabricatorHeraldApplication.php b/src/applications/herald/application/PhabricatorHeraldApplication.php index 0de1c02737..7808820818 100644 --- a/src/applications/herald/application/PhabricatorHeraldApplication.php +++ b/src/applications/herald/application/PhabricatorHeraldApplication.php @@ -49,6 +49,10 @@ final class PhabricatorHeraldApplication extends PhabricatorApplication { ); } + public function getMonograms() { + return array('H'); + } + public function getRoutes() { return array( '/H(?P[1-9]\d*)' => 'HeraldRuleViewController', diff --git a/src/applications/legalpad/application/PhabricatorLegalpadApplication.php b/src/applications/legalpad/application/PhabricatorLegalpadApplication.php index a3eaff5792..47a8f4ebef 100644 --- a/src/applications/legalpad/application/PhabricatorLegalpadApplication.php +++ b/src/applications/legalpad/application/PhabricatorLegalpadApplication.php @@ -48,6 +48,10 @@ final class PhabricatorLegalpadApplication extends PhabricatorApplication { 'open source projects keep track of Contributor License Agreements.'); } + public function getMonograms() { + return array('L'); + } + public function getRoutes() { return array( '/L(?P\d+)' => 'LegalpadDocumentSignController', diff --git a/src/applications/maniphest/application/PhabricatorManiphestApplication.php b/src/applications/maniphest/application/PhabricatorManiphestApplication.php index 8ed20416bb..9296060d81 100644 --- a/src/applications/maniphest/application/PhabricatorManiphestApplication.php +++ b/src/applications/maniphest/application/PhabricatorManiphestApplication.php @@ -42,6 +42,10 @@ final class PhabricatorManiphestApplication extends PhabricatorApplication { ); } + public function getMonograms() { + return array('T'); + } + public function getRoutes() { return array( '/T(?P[1-9]\d*)' => 'ManiphestTaskDetailController', diff --git a/src/applications/meta/controller/PhabricatorApplicationDetailViewController.php b/src/applications/meta/controller/PhabricatorApplicationDetailViewController.php index 8cceeb7396..1bf6734db3 100644 --- a/src/applications/meta/controller/PhabricatorApplicationDetailViewController.php +++ b/src/applications/meta/controller/PhabricatorApplicationDetailViewController.php @@ -38,6 +38,30 @@ final class PhabricatorApplicationDetailViewController $header->setStatus('fa-ban', 'dark', pht('Uninstalled')); } + if (!$selected->isFirstParty()) { + $header->addTag(id(new PHUITagView()) + ->setName('Extension') + ->setIcon('fa-plug') + ->setColor(PHUITagView::COLOR_INDIGO) + ->setType(PHUITagView::TYPE_SHADE)); + } + + if ($selected->isPrototype()) { + $header->addTag(id(new PHUITagView()) + ->setName('Prototype') + ->setIcon('fa-exclamation-circle') + ->setColor(PHUITagView::COLOR_ORANGE) + ->setType(PHUITagView::TYPE_SHADE)); + } + + if ($selected->isDeprecated()) { + $header->addTag(id(new PHUITagView()) + ->setName('Deprecated') + ->setIcon('fa-exclamation-triangle') + ->setColor(PHUITagView::COLOR_RED) + ->setType(PHUITagView::TYPE_SHADE)); + } + $timeline = $this->buildTransactionTimeline( $selected, new PhabricatorApplicationApplicationTransactionQuery()); @@ -95,6 +119,27 @@ final class PhabricatorApplicationDetailViewController phutil_tag('em', array(), $application->getFlavorText())); } + $phids = PhabricatorPHIDType::getAllTypesForApplication( + get_class($application)); + + $user_friendly_phids = array(); + foreach ($phids as $phid => $type) { + $user_friendly_phids[] = "PHID-{$phid} ({$type->getTypeName()})"; + } + + if ($user_friendly_phids) { + $properties->addProperty( + 'PHIDs', + phutil_implode_html(phutil_tag('br'), $user_friendly_phids)); + } + + $monograms = $application->getMonograms(); + if ($monograms) { + $properties->addProperty( + 'Monograms', + phutil_implode_html(', ', $monograms)); + } + if ($application->isPrototype()) { $proto_href = PhabricatorEnv::getDoclink( 'User Guide: Prototype Applications'); diff --git a/src/applications/meta/query/PhabricatorAppSearchEngine.php b/src/applications/meta/query/PhabricatorAppSearchEngine.php index e68570fe1c..08283afc2e 100644 --- a/src/applications/meta/query/PhabricatorAppSearchEngine.php +++ b/src/applications/meta/query/PhabricatorAppSearchEngine.php @@ -231,13 +231,13 @@ final class PhabricatorAppSearchEngine ->setSideColumn($configure); if (!$application->isFirstParty()) { - $tag = id(new PHUITagView()) + $extension_tag = id(new PHUITagView()) ->setName(pht('Extension')) - ->setIcon('fa-puzzle-piece') - ->setColor(PHUITagView::COLOR_BLUE) + ->setIcon('fa-plug') + ->setColor(PHUITagView::COLOR_INDIGO) ->setType(PHUITagView::TYPE_SHADE) ->setSlimShady(true); - $item->addAttribute($tag); + $item->addAttribute($extension_tag); } if ($application->isPrototype()) { @@ -250,6 +250,16 @@ final class PhabricatorAppSearchEngine $item->addAttribute($prototype_tag); } + if ($application->isDeprecated()) { + $deprecated_tag = id(new PHUITagView()) + ->setName(pht('Deprecated')) + ->setIcon('fa-exclamation-triangle') + ->setColor(PHUITagView::COLOR_RED) + ->setType(PHUITagView::TYPE_SHADE) + ->setSlimShady(true); + $item->addAttribute($deprecated_tag); + } + $item->addAttribute($description); if ($application->getBaseURI() && $application->isInstalled()) { diff --git a/src/applications/owners/application/PhabricatorOwnersApplication.php b/src/applications/owners/application/PhabricatorOwnersApplication.php index 3ef5f974d9..34bbc4b7b5 100644 --- a/src/applications/owners/application/PhabricatorOwnersApplication.php +++ b/src/applications/owners/application/PhabricatorOwnersApplication.php @@ -45,6 +45,10 @@ final class PhabricatorOwnersApplication extends PhabricatorApplication { ); } + public function getMonograms() { + return array('O'); + } + public function getRoutes() { return array( '/owners/' => array( diff --git a/src/applications/passphrase/application/PhabricatorPassphraseApplication.php b/src/applications/passphrase/application/PhabricatorPassphraseApplication.php index 2ab4f1e33d..ae79e5c8b5 100644 --- a/src/applications/passphrase/application/PhabricatorPassphraseApplication.php +++ b/src/applications/passphrase/application/PhabricatorPassphraseApplication.php @@ -34,6 +34,10 @@ final class PhabricatorPassphraseApplication extends PhabricatorApplication { return false; } + public function getMonograms() { + return array('K'); + } + public function getRoutes() { return array( '/K(?P\d+)' => 'PassphraseCredentialViewController', diff --git a/src/applications/paste/application/PhabricatorPasteApplication.php b/src/applications/paste/application/PhabricatorPasteApplication.php index 26e4b1740e..f6b6f7cf65 100644 --- a/src/applications/paste/application/PhabricatorPasteApplication.php +++ b/src/applications/paste/application/PhabricatorPasteApplication.php @@ -32,6 +32,10 @@ final class PhabricatorPasteApplication extends PhabricatorApplication { ); } + public function getMonograms() { + return array('P'); + } + public function getRoutes() { return array( '/P(?P[1-9]\d*)(?:\$(?P\d+(?:-\d+)?))?' diff --git a/src/applications/phame/application/PhabricatorPhameApplication.php b/src/applications/phame/application/PhabricatorPhameApplication.php index cd2eb4b487..b030673d1f 100644 --- a/src/applications/phame/application/PhabricatorPhameApplication.php +++ b/src/applications/phame/application/PhabricatorPhameApplication.php @@ -31,6 +31,10 @@ final class PhabricatorPhameApplication extends PhabricatorApplication { ); } + public function getMonograms() { + return array('J'); + } + public function getRoutes() { return array( '/J(?P[1-9]\d*)' => 'PhamePostViewController', diff --git a/src/applications/phid/type/PhabricatorPHIDType.php b/src/applications/phid/type/PhabricatorPHIDType.php index 2f82dcf169..f15df7f886 100644 --- a/src/applications/phid/type/PhabricatorPHIDType.php +++ b/src/applications/phid/type/PhabricatorPHIDType.php @@ -205,4 +205,28 @@ abstract class PhabricatorPHIDType extends Phobject { return $installed_types; } + + /** + * Get all PHID types of applications installed for a given viewer. + * + * @param PhabricatorUser Viewing user. + * @return dict Map of constants to installed + * types. + */ + public static function getAllTypesForApplication( + string $application) { + $all_types = self::getAllTypes(); + + $application_types = array(); + + foreach ($all_types as $key => $type) { + if ($type->getPHIDTypeApplicationClass() != $application) { + continue; + } + + $application_types[$key] = $type; + } + + return $application_types; + } } diff --git a/src/applications/pholio/application/PhabricatorPholioApplication.php b/src/applications/pholio/application/PhabricatorPholioApplication.php index 4d80dd12ae..5ac650cc20 100644 --- a/src/applications/pholio/application/PhabricatorPholioApplication.php +++ b/src/applications/pholio/application/PhabricatorPholioApplication.php @@ -32,6 +32,10 @@ final class PhabricatorPholioApplication extends PhabricatorApplication { ); } + public function getMonograms() { + return array('M'); + } + public function getRoutes() { return array( '/M(?P[1-9]\d*)(?:/(?P\d+)/)?' => 'PholioMockViewController', diff --git a/src/applications/phurl/application/PhabricatorPhurlApplication.php b/src/applications/phurl/application/PhabricatorPhurlApplication.php index 14ffda77f1..56290ef5e1 100644 --- a/src/applications/phurl/application/PhabricatorPhurlApplication.php +++ b/src/applications/phurl/application/PhabricatorPhurlApplication.php @@ -37,6 +37,10 @@ final class PhabricatorPhurlApplication extends PhabricatorApplication { ); } + public function getMonograms() { + return array('U'); + } + public function getRoutes() { return array( '/U(?P[1-9]\d*)/?' => 'PhabricatorPhurlURLViewController', diff --git a/src/applications/ponder/application/PhabricatorPonderApplication.php b/src/applications/ponder/application/PhabricatorPonderApplication.php index 56973447f9..e6f4ef8867 100644 --- a/src/applications/ponder/application/PhabricatorPonderApplication.php +++ b/src/applications/ponder/application/PhabricatorPonderApplication.php @@ -47,6 +47,10 @@ final class PhabricatorPonderApplication extends PhabricatorApplication { pht('Learn More'))); } + public function getMonograms() { + return array('Q'); + } + public function getRoutes() { return array( '/Q(?P[1-9]\d*)' diff --git a/src/applications/slowvote/application/PhabricatorSlowvoteApplication.php b/src/applications/slowvote/application/PhabricatorSlowvoteApplication.php index 1e4bd78419..8fa4edc6f6 100644 --- a/src/applications/slowvote/application/PhabricatorSlowvoteApplication.php +++ b/src/applications/slowvote/application/PhabricatorSlowvoteApplication.php @@ -45,6 +45,10 @@ final class PhabricatorSlowvoteApplication extends PhabricatorApplication { ); } + public function getMonograms() { + return array('V'); + } + public function getRoutes() { return array( '/V(?P[1-9]\d*)' => 'PhabricatorSlowvotePollController', diff --git a/src/applications/spaces/application/PhabricatorSpacesApplication.php b/src/applications/spaces/application/PhabricatorSpacesApplication.php index d542551ae4..f40538b69b 100644 --- a/src/applications/spaces/application/PhabricatorSpacesApplication.php +++ b/src/applications/spaces/application/PhabricatorSpacesApplication.php @@ -49,6 +49,10 @@ final class PhabricatorSpacesApplication extends PhabricatorApplication { ); } + public function getMonograms() { + return array('S'); + } + public function getRoutes() { return array( '/S(?P[1-9]\d*)' => 'PhabricatorSpacesViewController', From 5bd526646144e062f7c68e15ba07d03e6047adb6 Mon Sep 17 00:00:00 2001 From: bob Date: Wed, 22 Nov 2023 16:53:55 +0100 Subject: [PATCH 80/93] Fix a PHP 8.1 deprecated use of strlen with a NULL argument Summary: This call prevents users to view a commit in subversion repositories Indeed, if commiter and/or author field is not properly defined strlen is call with a NULL argument. Using strlen to check string validity is deprecated since PHP 8.1, phorge adopts phutil_nonempty_string() as a replacement. Note: this may highlight other absurd input values that might be worth correcting instead of just ignoring. If phutil_nonempty_string() throws an exception in your instance, report it to Phorge to evaluate and fix that specific corner case. Fix T15610 Test Plan: - Sign in (if needed) - Open a diffusion SVN repository - Open a commit without user name and or email - You should be able to view the commit Reviewers: O1 Blessed Committers, valerio.bozzolan Reviewed By: O1 Blessed Committers, valerio.bozzolan Subscribers: tobiaswiese, valerio.bozzolan, Matthew, Cigaryno Maniphest Tasks: T15610 Differential Revision: https://we.phorge.it/D25400 --- .../repository/storage/PhabricatorRepositoryCommit.php | 4 ++-- .../repository/storage/PhabricatorRepositoryCommitData.php | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/applications/repository/storage/PhabricatorRepositoryCommit.php b/src/applications/repository/storage/PhabricatorRepositoryCommit.php index 9e20a36676..ef3657d49f 100644 --- a/src/applications/repository/storage/PhabricatorRepositoryCommit.php +++ b/src/applications/repository/storage/PhabricatorRepositoryCommit.php @@ -478,7 +478,7 @@ final class PhabricatorRepositoryCommit } $author = $this->getRawAuthorStringForDisplay(); - if (strlen($author)) { + if (phutil_nonempty_string($author)) { return DiffusionView::renderName($author); } @@ -493,7 +493,7 @@ final class PhabricatorRepositoryCommit } $committer = $this->getRawCommitterStringForDisplay(); - if (strlen($committer)) { + if (phutil_nonempty_string($committer)) { return DiffusionView::renderName($committer); } diff --git a/src/applications/repository/storage/PhabricatorRepositoryCommitData.php b/src/applications/repository/storage/PhabricatorRepositoryCommitData.php index c77da64ec2..4726658b7a 100644 --- a/src/applications/repository/storage/PhabricatorRepositoryCommitData.php +++ b/src/applications/repository/storage/PhabricatorRepositoryCommitData.php @@ -131,7 +131,7 @@ final class PhabricatorRepositoryCommitData extends PhabricatorRepositoryDAO { $ref = $this->getCommitRef(); $committer = $ref->getCommitter(); - if (strlen($committer)) { + if (phutil_nonempty_string($committer)) { return $committer; } From acfb44d6679edc87e9f209f011e77ee2594cd8ae Mon Sep 17 00:00:00 2001 From: bob Date: Wed, 22 Nov 2023 16:55:08 +0100 Subject: [PATCH 81/93] Fix a PHP 8.1 deprecated use of strlen with a NULL argument on commit page Summary: With PHP 8.1+ it is not possible to view a commit if the author field is not properly defined Indeed, if the commit author is not properly defined, strlen(null) is called, causing a deprecation warning, elevated to exception. Using strlen() to check string validity is deprecated since PHP 8.1. Phorge adopts phutil_nonempty_string() as a replacement. Fix T15628 Test Plan: - Push a new commit on a subversion repository (since T15629 is not yet addressed) - Visualize the commit - You should not get a RuntimeException Reviewers: O1 Blessed Committers, Sten, valerio.bozzolan Reviewed By: O1 Blessed Committers, Sten, valerio.bozzolan Subscribers: Sten, tobiaswiese, valerio.bozzolan, Matthew, Cigaryno Maniphest Tasks: T15628 Differential Revision: https://we.phorge.it/D25422 --- .../repository/storage/PhabricatorRepositoryCommitData.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/applications/repository/storage/PhabricatorRepositoryCommitData.php b/src/applications/repository/storage/PhabricatorRepositoryCommitData.php index 4726658b7a..96508a2452 100644 --- a/src/applications/repository/storage/PhabricatorRepositoryCommitData.php +++ b/src/applications/repository/storage/PhabricatorRepositoryCommitData.php @@ -97,7 +97,7 @@ final class PhabricatorRepositoryCommitData extends PhabricatorRepositoryDAO { $ref = $this->getCommitRef(); $author = $ref->getAuthor(); - if (strlen($author)) { + if (phutil_nonempty_string($author)) { return $author; } From cf8d5d60a594f2f172450879327caac0f0e6afc8 Mon Sep 17 00:00:00 2001 From: bob Date: Wed, 22 Nov 2023 16:56:01 +0100 Subject: [PATCH 82/93] Fix a PHP 8.1 deprecated use of strlen with a NULL argument in commit parser Summary: With PHP 8.1+ it is not possible to import a commit if the commiter field is not properly defined Indeed, if the committer is not properly defined, strlen(null) is called, causing a deprecation warning, elevated to exception. Using strlen() to check string validity is deprecated since PHP 8.1. Phorge adopts phutil_nonempty_string() as a replacement. Fix T15629 Test Plan: - Push a commit to an observed subversion repository - Import it via the phorge/bin/repository reparse COMMIT_ID --importing - The commit should be properly imported and available in Diffusion Reviewers: O1 Blessed Committers, Sten, valerio.bozzolan Reviewed By: O1 Blessed Committers, Sten, valerio.bozzolan Subscribers: Sten, tobiaswiese, valerio.bozzolan, Matthew, Cigaryno Maniphest Tasks: T15629 Differential Revision: https://we.phorge.it/D25423 --- .../PhabricatorRepositoryCommitMessageParserWorker.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/applications/repository/worker/commitmessageparser/PhabricatorRepositoryCommitMessageParserWorker.php b/src/applications/repository/worker/commitmessageparser/PhabricatorRepositoryCommitMessageParserWorker.php index a0ea2d84b2..fc0bd42477 100644 --- a/src/applications/repository/worker/commitmessageparser/PhabricatorRepositoryCommitMessageParserWorker.php +++ b/src/applications/repository/worker/commitmessageparser/PhabricatorRepositoryCommitMessageParserWorker.php @@ -36,7 +36,7 @@ abstract class PhabricatorRepositoryCommitMessageParserWorker $author = $ref->getAuthor(); $committer = $ref->getCommitter(); - $has_committer = (bool)strlen($committer); + $has_committer = phutil_nonempty_string($committer); $identity_engine = id(new DiffusionRepositoryIdentityEngine()) ->setViewer($viewer) From 4d4712b58d2a4c9856d9d462e4737eac08604f09 Mon Sep 17 00:00:00 2001 From: Matthew Bowker Date: Mon, 27 Nov 2023 11:36:12 -0700 Subject: [PATCH 83/93] Remove Chatlog entirely Summary: This commit removes ChatLog entirely. All of the application files are removed, and the migrations used are stubbed out. I stubbed the migrations as that allows for existing installs to make no changes, but new installs will not create the database. Fixes T15126 Test Plan: Loaded up http://phorge.local/chatlog and confirmed the 404. Loaded up http://phorge.local/applications/view/PhabricatorChatLogApplication and confirmed the 404. Created a new database prefix and ran `bin/storage upgrade` against it, confirmed that the chatlog database was not created. Restored another prefix (an old one) and ran `bin/storage upgrade` and confirmed database was not deleted. Reviewers: O1 Blessed Committers, avivey Reviewed By: O1 Blessed Committers, avivey Subscribers: avivey, tobiaswiese, valerio.bozzolan, Cigaryno Maniphest Tasks: T15126 Differential Revision: https://we.phorge.it/D25480 --- resources/celerity/map.php | 2 - .../sql/autopatches/20140722.appname.php | 1 - resources/sql/patches/106.chatlog.sql | 11 +- .../116.utf8-backup-first-expect-wait.sql | 18 - .../sql/patches/20130214.chatlogchannel.sql | 12 +- .../sql/patches/20130214.chatlogchannelid.sql | 3 +- .../sql/patches/20130218.updatechannelid.php | 63 +--- .../sql/patches/20130222.dropchannel.sql | 3 +- resources/sql/quickstart.sql | 39 --- src/__phutil_library_map__.php | 30 -- .../PhabricatorChatLogApplication.php | 47 --- .../conduit/ChatLogConduitAPIMethod.php | 9 - .../conduit/ChatLogQueryConduitAPIMethod.php | 59 ---- .../conduit/ChatLogRecordConduitAPIMethod.php | 72 ---- ...habricatorChatLogChannelListController.php | 41 --- ...PhabricatorChatLogChannelLogController.php | 320 ------------------ .../PhabricatorChatLogController.php | 3 - .../query/PhabricatorChatLogChannelQuery.php | 63 ---- .../chatlog/query/PhabricatorChatLogQuery.php | 84 ----- .../storage/PhabricatorChatLogChannel.php | 51 --- .../chatlog/storage/PhabricatorChatLogDAO.php | 9 - .../storage/PhabricatorChatLogEvent.php | 59 ---- src/docs/book/phorge.book | 4 - .../patch/PhabricatorBuiltinPatchList.php | 1 - .../rsrc/css/application/chatlog/chatlog.css | 81 ----- 25 files changed, 5 insertions(+), 1080 deletions(-) delete mode 100644 src/applications/chatlog/application/PhabricatorChatLogApplication.php delete mode 100644 src/applications/chatlog/conduit/ChatLogConduitAPIMethod.php delete mode 100644 src/applications/chatlog/conduit/ChatLogQueryConduitAPIMethod.php delete mode 100644 src/applications/chatlog/conduit/ChatLogRecordConduitAPIMethod.php delete mode 100644 src/applications/chatlog/controller/PhabricatorChatLogChannelListController.php delete mode 100644 src/applications/chatlog/controller/PhabricatorChatLogChannelLogController.php delete mode 100644 src/applications/chatlog/controller/PhabricatorChatLogController.php delete mode 100644 src/applications/chatlog/query/PhabricatorChatLogChannelQuery.php delete mode 100644 src/applications/chatlog/query/PhabricatorChatLogQuery.php delete mode 100644 src/applications/chatlog/storage/PhabricatorChatLogChannel.php delete mode 100644 src/applications/chatlog/storage/PhabricatorChatLogDAO.php delete mode 100644 src/applications/chatlog/storage/PhabricatorChatLogEvent.php delete mode 100644 webroot/rsrc/css/application/chatlog/chatlog.css diff --git a/resources/celerity/map.php b/resources/celerity/map.php index fca4e57058..5fc371bcf0 100644 --- a/resources/celerity/map.php +++ b/resources/celerity/map.php @@ -42,7 +42,6 @@ return array( 'rsrc/css/application/base/notification-menu.css' => '4df1ee30', 'rsrc/css/application/base/phui-theme.css' => '35883b37', 'rsrc/css/application/base/standard-page-view.css' => 'e08c7462', - 'rsrc/css/application/chatlog/chatlog.css' => 'abdc76ee', 'rsrc/css/application/conduit/conduit-api.css' => 'ce2cfc41', 'rsrc/css/application/config/config-options.css' => '16c920ae', 'rsrc/css/application/config/config-template.css' => 'e689dbbd', @@ -770,7 +769,6 @@ return array( 'people-profile-css' => '2ea2daa1', 'phabricator-action-list-view-css' => '1b0085b2', 'phabricator-busy' => '5202e831', - 'phabricator-chatlog-css' => 'abdc76ee', 'phabricator-content-source-view-css' => 'cdf0d579', 'phabricator-core-css' => 'b3a5928e', 'phabricator-countdown-css' => 'bff8012f', diff --git a/resources/sql/autopatches/20140722.appname.php b/resources/sql/autopatches/20140722.appname.php index dd8e929357..2a337c35aa 100644 --- a/resources/sql/autopatches/20140722.appname.php +++ b/resources/sql/autopatches/20140722.appname.php @@ -4,7 +4,6 @@ $applications = array( 'Audit', 'Auth', 'Calendar', - 'ChatLog', 'Conduit', 'Config', 'Conpherence', diff --git a/resources/sql/patches/106.chatlog.sql b/resources/sql/patches/106.chatlog.sql index bbb9be945e..04b0e849bc 100644 --- a/resources/sql/patches/106.chatlog.sql +++ b/resources/sql/patches/106.chatlog.sql @@ -1,10 +1 @@ -CREATE TABLE {$NAMESPACE}_chatlog.chatlog_event ( - id INT UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT, - channel VARCHAR(64) BINARY NOT NULL, - epoch INT UNSIGNED NOT NULL, - author VARCHAR(64) BINARY NOT NULL, - type VARCHAR(4) NOT NULL, - message LONGBLOB NOT NULL, - loggedByPHID VARCHAR(64) BINARY NOT NULL, - KEY (channel, epoch) -); +/* This file is intentionally left empty, see T15126 */ diff --git a/resources/sql/patches/116.utf8-backup-first-expect-wait.sql b/resources/sql/patches/116.utf8-backup-first-expect-wait.sql index eda5573641..5f00c03e38 100644 --- a/resources/sql/patches/116.utf8-backup-first-expect-wait.sql +++ b/resources/sql/patches/116.utf8-backup-first-expect-wait.sql @@ -16,24 +16,6 @@ ALTER TABLE `{$NAMESPACE}_audit`.`audit_comment` -ALTER DATABASE `{$NAMESPACE}_chatlog` COLLATE utf8_general_ci; - -ALTER TABLE `{$NAMESPACE}_chatlog`.`chatlog_event` - MODIFY `channel` varchar(64) CHARACTER SET binary, - MODIFY `author` varchar(64) CHARACTER SET binary, - MODIFY `type` varchar(4) CHARACTER SET binary, - MODIFY `message` longtext CHARACTER SET binary, - MODIFY `loggedByPHID` varchar(64) CHARACTER SET binary; -ALTER TABLE `{$NAMESPACE}_chatlog`.`chatlog_event` - COLLATE utf8_general_ci, - MODIFY `channel` varchar(64) COLLATE utf8_bin NOT NULL, - MODIFY `author` varchar(64) COLLATE utf8_bin NOT NULL, - MODIFY `type` varchar(4) COLLATE utf8_general_ci NOT NULL, - MODIFY `message` longtext COLLATE utf8_bin NOT NULL, - MODIFY `loggedByPHID` varchar(64) COLLATE utf8_bin NOT NULL; - - - ALTER DATABASE `{$NAMESPACE}_conduit` COLLATE utf8_general_ci; ALTER TABLE `{$NAMESPACE}_conduit`.`conduit_certificatetoken` diff --git a/resources/sql/patches/20130214.chatlogchannel.sql b/resources/sql/patches/20130214.chatlogchannel.sql index 6bb0a777ac..04b0e849bc 100644 --- a/resources/sql/patches/20130214.chatlogchannel.sql +++ b/resources/sql/patches/20130214.chatlogchannel.sql @@ -1,11 +1 @@ -CREATE TABLE {$NAMESPACE}_chatlog.chatlog_channel ( - id INT UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT, - serviceName VARCHAR(64) COLLATE utf8_bin NOT NULL, - serviceType VARCHAR(32) COLLATE utf8_bin NOT NULL, - channelName VARCHAR(64) COLLATE utf8_bin NOT NULL, - viewPolicy VARCHAR(64) COLLATE utf8_bin NOT NULL, - editPolicy VARCHAR(64) COLLATE utf8_bin NOT NULL, - dateCreated INT UNSIGNED NOT NULL, - dateModified INT UNSIGNED NOT NULL, - UNIQUE KEY `key_channel` (channelName, serviceType, serviceName) -)ENGINE=InnoDB DEFAULT CHARSET=utf8; +/* This file is intentionally left empty, see T15126 */ diff --git a/resources/sql/patches/20130214.chatlogchannelid.sql b/resources/sql/patches/20130214.chatlogchannelid.sql index bc522e205c..04b0e849bc 100644 --- a/resources/sql/patches/20130214.chatlogchannelid.sql +++ b/resources/sql/patches/20130214.chatlogchannelid.sql @@ -1,2 +1 @@ -ALTER TABLE `{$NAMESPACE}_chatlog`.`chatlog_event` - ADD `channelID` INT UNSIGNED NOT NULL; +/* This file is intentionally left empty, see T15126 */ diff --git a/resources/sql/patches/20130218.updatechannelid.php b/resources/sql/patches/20130218.updatechannelid.php index cf60544a3b..38ec156d06 100644 --- a/resources/sql/patches/20130218.updatechannelid.php +++ b/resources/sql/patches/20130218.updatechannelid.php @@ -1,64 +1,3 @@ openTransaction(); -$channel_table->openTransaction(); - -$event_table->beginReadLocking(); -$channel_table->beginReadLocking(); - -$events = new LiskMigrationIterator($event_table); -$conn_w = $channel_table->establishConnection('w'); - -foreach ($events as $event) { - if ($event->getChannelID()) { - continue; - } - - $event_row = queryfx_one( - $conn_w, - 'SELECT channel FROM %T WHERE id = %d', - $event->getTableName(), - $event->getID()); - $event_channel = $event_row['channel']; - - $matched = queryfx_one( - $conn_w, - 'SELECT * FROM %T WHERE - channelName = %s AND serviceName = %s AND serviceType = %s', - $channel_table->getTableName(), - $event_channel, - '', - ''); - - if (!$matched) { - $matched = id(new PhabricatorChatLogChannel()) - ->setChannelName($event_channel) - ->setServiceType('') - ->setServiceName('') - ->setViewPolicy(PhabricatorPolicies::POLICY_USER) - ->setEditPolicy(PhabricatorPolicies::POLICY_USER) - ->save(); - $matched_id = $matched->getID(); - } else { - $matched_id = $matched['id']; - } - - queryfx( - $event->establishConnection('w'), - 'UPDATE %T SET channelID = %d WHERE id = %d', - $event->getTableName(), - $matched_id, - $event->getID()); -} - -$event_table->endReadLocking(); -$channel_table->endReadLocking(); - -$event_table->saveTransaction(); -$channel_table->saveTransaction(); - -echo "\n".pht('Done.')."\n"; +/* This file is intentionally left empty, see T15126 */ diff --git a/resources/sql/patches/20130222.dropchannel.sql b/resources/sql/patches/20130222.dropchannel.sql index 00e6a13f18..04b0e849bc 100644 --- a/resources/sql/patches/20130222.dropchannel.sql +++ b/resources/sql/patches/20130222.dropchannel.sql @@ -1,2 +1 @@ -ALTER TABLE `{$NAMESPACE}_chatlog`.`chatlog_event` - DROP channel; +/* This file is intentionally left empty, see T15126 */ diff --git a/resources/sql/quickstart.sql b/resources/sql/quickstart.sql index b2796d31e6..2df0d4f252 100644 --- a/resources/sql/quickstart.sql +++ b/resources/sql/quickstart.sql @@ -1477,45 +1477,6 @@ CREATE TABLE `edgedata` ( PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET={$CHARSET} COLLATE={$COLLATE_TEXT}; -CREATE DATABASE /*!32312 IF NOT EXISTS*/ `{$NAMESPACE}_chatlog` /*!40100 DEFAULT CHARACTER SET {$CHARSET} COLLATE {$COLLATE_TEXT} */; - -USE `{$NAMESPACE}_chatlog`; - - SET NAMES utf8 ; - - SET character_set_client = {$CHARSET} ; - -CREATE TABLE `chatlog_channel` ( - `id` int(10) unsigned NOT NULL AUTO_INCREMENT, - `serviceName` varchar(64) CHARACTER SET {$CHARSET} COLLATE {$COLLATE_TEXT} NOT NULL, - `serviceType` varchar(32) CHARACTER SET {$CHARSET} COLLATE {$COLLATE_TEXT} NOT NULL, - `channelName` varchar(64) CHARACTER SET {$CHARSET} COLLATE {$COLLATE_TEXT} NOT NULL, - `viewPolicy` varbinary(64) NOT NULL, - `editPolicy` varbinary(64) NOT NULL, - `dateCreated` int(10) unsigned NOT NULL, - `dateModified` int(10) unsigned NOT NULL, - PRIMARY KEY (`id`), - UNIQUE KEY `key_channel` (`channelName`,`serviceType`,`serviceName`) -) ENGINE=InnoDB DEFAULT CHARSET={$CHARSET} COLLATE={$COLLATE_TEXT}; - -USE `{$NAMESPACE}_chatlog`; - - SET NAMES utf8 ; - - SET character_set_client = {$CHARSET} ; - -CREATE TABLE `chatlog_event` ( - `id` int(10) unsigned NOT NULL AUTO_INCREMENT, - `epoch` int(10) unsigned NOT NULL, - `author` varchar(64) CHARACTER SET {$CHARSET} COLLATE {$COLLATE_TEXT} NOT NULL, - `type` varchar(4) CHARACTER SET {$CHARSET} COLLATE {$COLLATE_TEXT} NOT NULL, - `message` longtext CHARACTER SET {$CHARSET} COLLATE {$COLLATE_TEXT} NOT NULL, - `loggedByPHID` varbinary(64) NOT NULL, - `channelID` int(10) unsigned NOT NULL, - PRIMARY KEY (`id`), - KEY `channel` (`epoch`) -) ENGINE=InnoDB DEFAULT CHARSET={$CHARSET} COLLATE={$COLLATE_TEXT}; - CREATE DATABASE /*!32312 IF NOT EXISTS*/ `{$NAMESPACE}_conduit` /*!40100 DEFAULT CHARACTER SET {$CHARSET} COLLATE {$COLLATE_TEXT} */; USE `{$NAMESPACE}_conduit`; diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php index ad0d8fc937..f2a39023e4 100644 --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -339,9 +339,6 @@ phutil_register_library_map(array( 'CelerityResourcesOnDisk' => 'applications/celerity/resources/CelerityResourcesOnDisk.php', 'CeleritySpriteGenerator' => 'applications/celerity/CeleritySpriteGenerator.php', 'CelerityStaticResourceResponse' => 'applications/celerity/CelerityStaticResourceResponse.php', - 'ChatLogConduitAPIMethod' => 'applications/chatlog/conduit/ChatLogConduitAPIMethod.php', - 'ChatLogQueryConduitAPIMethod' => 'applications/chatlog/conduit/ChatLogQueryConduitAPIMethod.php', - 'ChatLogRecordConduitAPIMethod' => 'applications/chatlog/conduit/ChatLogRecordConduitAPIMethod.php', 'ConduitAPIDocumentationPage' => 'applications/conduit/data/ConduitAPIDocumentationPage.php', 'ConduitAPIMethod' => 'applications/conduit/method/ConduitAPIMethod.php', 'ConduitAPIMethodTestCase' => 'applications/conduit/method/__tests__/ConduitAPIMethodTestCase.php', @@ -2808,15 +2805,6 @@ phutil_register_library_map(array( 'PhabricatorChartInterval' => 'applications/fact/chart/PhabricatorChartInterval.php', 'PhabricatorChartRenderingEngine' => 'applications/fact/engine/PhabricatorChartRenderingEngine.php', 'PhabricatorChartStackedAreaDataset' => 'applications/fact/chart/PhabricatorChartStackedAreaDataset.php', - 'PhabricatorChatLogApplication' => 'applications/chatlog/application/PhabricatorChatLogApplication.php', - 'PhabricatorChatLogChannel' => 'applications/chatlog/storage/PhabricatorChatLogChannel.php', - 'PhabricatorChatLogChannelListController' => 'applications/chatlog/controller/PhabricatorChatLogChannelListController.php', - 'PhabricatorChatLogChannelLogController' => 'applications/chatlog/controller/PhabricatorChatLogChannelLogController.php', - 'PhabricatorChatLogChannelQuery' => 'applications/chatlog/query/PhabricatorChatLogChannelQuery.php', - 'PhabricatorChatLogController' => 'applications/chatlog/controller/PhabricatorChatLogController.php', - 'PhabricatorChatLogDAO' => 'applications/chatlog/storage/PhabricatorChatLogDAO.php', - 'PhabricatorChatLogEvent' => 'applications/chatlog/storage/PhabricatorChatLogEvent.php', - 'PhabricatorChatLogQuery' => 'applications/chatlog/query/PhabricatorChatLogQuery.php', 'PhabricatorCheckboxesEditField' => 'applications/transactions/editfield/PhabricatorCheckboxesEditField.php', 'PhabricatorChunkedFileStorageEngine' => 'applications/files/engine/PhabricatorChunkedFileStorageEngine.php', 'PhabricatorClassConfigType' => 'applications/config/type/PhabricatorClassConfigType.php', @@ -6339,9 +6327,6 @@ phutil_register_library_map(array( 'CelerityResourcesOnDisk' => 'CelerityPhysicalResources', 'CeleritySpriteGenerator' => 'Phobject', 'CelerityStaticResourceResponse' => 'Phobject', - 'ChatLogConduitAPIMethod' => 'ConduitAPIMethod', - 'ChatLogQueryConduitAPIMethod' => 'ChatLogConduitAPIMethod', - 'ChatLogRecordConduitAPIMethod' => 'ChatLogConduitAPIMethod', 'ConduitAPIDocumentationPage' => 'Phobject', 'ConduitAPIMethod' => array( 'Phobject', @@ -9191,21 +9176,6 @@ phutil_register_library_map(array( 'PhabricatorChartInterval' => 'Phobject', 'PhabricatorChartRenderingEngine' => 'Phobject', 'PhabricatorChartStackedAreaDataset' => 'PhabricatorChartDataset', - 'PhabricatorChatLogApplication' => 'PhabricatorApplication', - 'PhabricatorChatLogChannel' => array( - 'PhabricatorChatLogDAO', - 'PhabricatorPolicyInterface', - ), - 'PhabricatorChatLogChannelListController' => 'PhabricatorChatLogController', - 'PhabricatorChatLogChannelLogController' => 'PhabricatorChatLogController', - 'PhabricatorChatLogChannelQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', - 'PhabricatorChatLogController' => 'PhabricatorController', - 'PhabricatorChatLogDAO' => 'PhabricatorLiskDAO', - 'PhabricatorChatLogEvent' => array( - 'PhabricatorChatLogDAO', - 'PhabricatorPolicyInterface', - ), - 'PhabricatorChatLogQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', 'PhabricatorCheckboxesEditField' => 'PhabricatorEditField', 'PhabricatorChunkedFileStorageEngine' => 'PhabricatorFileStorageEngine', 'PhabricatorClassConfigType' => 'PhabricatorTextConfigType', diff --git a/src/applications/chatlog/application/PhabricatorChatLogApplication.php b/src/applications/chatlog/application/PhabricatorChatLogApplication.php deleted file mode 100644 index ab5eb1960f..0000000000 --- a/src/applications/chatlog/application/PhabricatorChatLogApplication.php +++ /dev/null @@ -1,47 +0,0 @@ - array( - '' => 'PhabricatorChatLogChannelListController', - 'channel/(?P[^/]+)/' - => 'PhabricatorChatLogChannelLogController', - ), - ); - } - -} diff --git a/src/applications/chatlog/conduit/ChatLogConduitAPIMethod.php b/src/applications/chatlog/conduit/ChatLogConduitAPIMethod.php deleted file mode 100644 index e524ef60da..0000000000 --- a/src/applications/chatlog/conduit/ChatLogConduitAPIMethod.php +++ /dev/null @@ -1,9 +0,0 @@ - 'optional list', - 'limit' => 'optional int (default = 100)', - ); - } - - protected function defineReturnType() { - return 'nonempty list'; - } - - protected function execute(ConduitAPIRequest $request) { - $query = new PhabricatorChatLogQuery(); - - $channel_ids = $request->getValue('channelIDs'); - if ($channel_ids) { - $query->withChannelIDs($channel_ids); - } - - $limit = $request->getValue('limit'); - if (!$limit) { - $limit = 100; - } - $query->setLimit($limit); - - $logs = $query->execute(); - - $results = array(); - foreach ($logs as $log) { - $results[] = array( - 'channelID' => $log->getChannelID(), - 'epoch' => $log->getEpoch(), - 'author' => $log->getAuthor(), - 'type' => $log->getType(), - 'message' => $log->getMessage(), - 'loggedByPHID' => $log->getLoggedByPHID(), - ); - } - - return $results; - } - -} diff --git a/src/applications/chatlog/conduit/ChatLogRecordConduitAPIMethod.php b/src/applications/chatlog/conduit/ChatLogRecordConduitAPIMethod.php deleted file mode 100644 index fe972222ae..0000000000 --- a/src/applications/chatlog/conduit/ChatLogRecordConduitAPIMethod.php +++ /dev/null @@ -1,72 +0,0 @@ - 'required list', - ); - } - - protected function defineReturnType() { - return 'list'; - } - - protected function execute(ConduitAPIRequest $request) { - $logs = $request->getValue('logs'); - if (!is_array($logs)) { - $logs = array(); - } - - $template = new PhabricatorChatLogEvent(); - $template->setLoggedByPHID($request->getUser()->getPHID()); - - $objs = array(); - foreach ($logs as $log) { - $channel_name = idx($log, 'channel'); - $service_name = idx($log, 'serviceName'); - $service_type = idx($log, 'serviceType'); - - $channel = id(new PhabricatorChatLogChannel())->loadOneWhere( - 'channelName = %s AND serviceName = %s AND serviceType = %s', - $channel_name, - $service_name, - $service_type); - - if (!$channel) { - $channel = id(new PhabricatorChatLogChannel()) - ->setChannelName($channel_name) - ->setserviceName($service_name) - ->setServiceType($service_type) - ->setViewPolicy(PhabricatorPolicies::POLICY_USER) - ->setEditPolicy(PhabricatorPolicies::POLICY_USER) - ->save(); - } - - $obj = clone $template; - $obj->setChannelID($channel->getID()); - $obj->setType(idx($log, 'type')); - $obj->setAuthor(idx($log, 'author')); - $obj->setEpoch(idx($log, 'epoch')); - $obj->setMessage(idx($log, 'message')); - $obj->save(); - - $objs[] = $obj; - } - - return array_values(mpull($objs, 'getID')); - } - -} diff --git a/src/applications/chatlog/controller/PhabricatorChatLogChannelListController.php b/src/applications/chatlog/controller/PhabricatorChatLogChannelListController.php deleted file mode 100644 index 530c26770a..0000000000 --- a/src/applications/chatlog/controller/PhabricatorChatLogChannelListController.php +++ /dev/null @@ -1,41 +0,0 @@ -getViewer(); - - $channels = id(new PhabricatorChatLogChannelQuery()) - ->setViewer($viewer) - ->execute(); - - $list = new PHUIObjectItemListView(); - foreach ($channels as $channel) { - $item = id(new PHUIObjectItemView()) - ->setHeader($channel->getChannelName()) - ->setHref('/chatlog/channel/'.$channel->getID().'/') - ->addAttribute($channel->getServiceName()) - ->addAttribute($channel->getServiceType()); - $list->addItem($item); - } - - $crumbs = $this - ->buildApplicationCrumbs() - ->addTextCrumb(pht('Channel List'), $this->getApplicationURI()); - - $box = id(new PHUIObjectBoxView()) - ->setHeaderText('Channel List') - ->setObjectList($list); - - return $this->newPage() - ->setTitle(pht('Channel List')) - ->setCrumbs($crumbs) - ->appendChild($box); - - } -} diff --git a/src/applications/chatlog/controller/PhabricatorChatLogChannelLogController.php b/src/applications/chatlog/controller/PhabricatorChatLogChannelLogController.php deleted file mode 100644 index b9893f6924..0000000000 --- a/src/applications/chatlog/controller/PhabricatorChatLogChannelLogController.php +++ /dev/null @@ -1,320 +0,0 @@ -getViewer(); - $id = $request->getURIData('channelID'); - - $uri = new PhutilURI($request->getPath()); - - $pager = new AphrontCursorPagerView(); - $pager->setURI($uri); - $pager->setPageSize(250); - - $query = id(new PhabricatorChatLogQuery()) - ->setViewer($viewer) - ->withChannelIDs(array($id)); - - $channel = id(new PhabricatorChatLogChannelQuery()) - ->setViewer($viewer) - ->withIDs(array($id)) - ->executeOne(); - - if (!$channel) { - return new Aphront404Response(); - } - - list($after, $before, $map) = $this->getPagingParameters($request, $query); - - $pager->setAfterID($after); - $pager->setBeforeID($before); - - $logs = $query->executeWithCursorPager($pager); - - // Show chat logs oldest-first. - $logs = array_reverse($logs); - - - // Divide all the logs into blocks, where a block is the same author saying - // several things in a row. A block ends when another user speaks, or when - // two minutes pass without the author speaking. - - $blocks = array(); - $block = null; - - $last_author = null; - $last_epoch = null; - foreach ($logs as $log) { - $this_author = $log->getAuthor(); - $this_epoch = $log->getEpoch(); - - // Decide whether we should start a new block or not. - $new_block = ($this_author !== $last_author) || - ($this_epoch - (60 * 2) > $last_epoch); - - if ($new_block) { - if ($block) { - $blocks[] = $block; - } - $block = array( - 'id' => $log->getID(), - 'epoch' => $this_epoch, - 'author' => $this_author, - 'logs' => array($log), - ); - } else { - $block['logs'][] = $log; - } - - $last_author = $this_author; - $last_epoch = $this_epoch; - } - if ($block) { - $blocks[] = $block; - } - - // Figure out CSS classes for the blocks. We alternate colors between - // lines, and highlight the entire block which contains the target ID or - // date, if applicable. - - foreach ($blocks as $key => $block) { - $classes = array(); - if ($key % 2) { - $classes[] = 'alternate'; - } - $ids = mpull($block['logs'], 'getID', 'getID'); - if (array_intersect_key($ids, $map)) { - $classes[] = 'highlight'; - } - $blocks[$key]['class'] = $classes ? implode(' ', $classes) : null; - } - - - require_celerity_resource('phabricator-chatlog-css'); - - $out = array(); - foreach ($blocks as $block) { - $author = $block['author']; - $author = id(new PhutilUTF8StringTruncator()) - ->setMaximumGlyphs(18) - ->truncateString($author); - $author = phutil_tag('td', array('class' => 'author'), $author); - - $href = $uri->alter('at', $block['id']); - $timestamp = $block['epoch']; - $timestamp = phabricator_datetime($timestamp, $viewer); - $timestamp = phutil_tag( - 'a', - array( - 'href' => $href, - 'class' => 'timestamp', - ), - $timestamp); - - $message = mpull($block['logs'], 'getMessage'); - $message = implode("\n", $message); - $message = phutil_tag( - 'td', - array( - 'class' => 'message', - ), - array( - $timestamp, - $message, - )); - - $out[] = phutil_tag( - 'tr', - array( - 'class' => $block['class'], - ), - array( - $author, - $message, - )); - } - - $links = array(); - - $first_uri = $pager->getFirstPageURI(); - if ($first_uri) { - $links[] = phutil_tag( - 'a', - array( - 'href' => $first_uri, - ), - "\xC2\xAB ".pht('Newest')); - } - - $prev_uri = $pager->getPrevPageURI(); - if ($prev_uri) { - $links[] = phutil_tag( - 'a', - array( - 'href' => $prev_uri, - ), - "\xE2\x80\xB9 ".pht('Newer')); - } - - $next_uri = $pager->getNextPageURI(); - if ($next_uri) { - $links[] = phutil_tag( - 'a', - array( - 'href' => $next_uri, - ), - pht('Older')." \xE2\x80\xBA"); - } - - $pager_bottom = phutil_tag( - 'div', - array('class' => 'phabricator-chat-log-pager-bottom'), - $links); - - $crumbs = $this - ->buildApplicationCrumbs() - ->addTextCrumb($channel->getChannelName(), $uri); - - $form = id(new AphrontFormView()) - ->setUser($viewer) - ->setMethod('GET') - ->setAction($uri) - ->appendChild( - id(new AphrontFormTextControl()) - ->setLabel(pht('Date')) - ->setName('date') - ->setValue($request->getStr('date'))) - ->appendChild( - id(new AphrontFormSubmitControl()) - ->setValue(pht('Jump'))); - - $table = phutil_tag( - 'table', - array( - 'class' => 'phabricator-chat-log', - ), - $out); - - $log = phutil_tag( - 'div', - array( - 'class' => 'phabricator-chat-log-panel', - ), - $table); - - $jump_link = id(new PHUIButtonView()) - ->setTag('a') - ->setHref('#latest') - ->setText(pht('Jump to Bottom')) - ->setIcon('fa-arrow-circle-down'); - - $jump_target = phutil_tag( - 'div', - array( - 'id' => 'latest', - )); - - $content = phutil_tag( - 'div', - array( - 'class' => 'phabricator-chat-log-wrap', - ), - array( - $log, - $jump_target, - $pager_bottom, - )); - - $header = id(new PHUIHeaderView()) - ->setHeader($channel->getChannelName()) - ->setSubHeader($channel->getServiceName()) - ->addActionLink($jump_link); - - $box = id(new PHUIObjectBoxView()) - ->setHeader($header) - ->setCollapsed(true) - ->appendChild($content); - - $box->setShowHide( - pht('Search Dates'), - pht('Hide Dates'), - $form, - '#'); - - return $this->newPage() - ->setTitle(pht('Channel Log')) - ->setCrumbs($crumbs) - ->appendChild($box); - - } - - /** - * From request parameters, figure out where we should jump to in the log. - * We jump to either a date or log ID, but load a few lines of context before - * it so the user can see the nearby conversation. - */ - private function getPagingParameters( - AphrontRequest $request, - PhabricatorChatLogQuery $query) { - - $viewer = $request->getViewer(); - - $at_id = $request->getInt('at'); - $at_date = $request->getStr('date'); - - $context_log = null; - $map = array(); - - $query = clone $query; - $query->setLimit(8); - - if ($at_id) { - // Jump to the log in question, and load a few lines of context before - // it. - $context_logs = $query - ->setAfterID($at_id) - ->execute(); - - $context_log = last($context_logs); - - $map = array( - $at_id => true, - ); - - } else if ($at_date) { - $timestamp = PhabricatorTime::parseLocalTime($at_date, $viewer); - - if ($timestamp) { - $context_logs = $query - ->withMaximumEpoch($timestamp) - ->execute(); - - $context_log = last($context_logs); - - $target_log = head($context_logs); - if ($target_log) { - $map = array( - $target_log->getID() => true, - ); - } - } - } - - if ($context_log) { - $after = null; - $before = $context_log->getID() - 1; - } else { - $after = $request->getInt('after'); - $before = $request->getInt('before'); - } - - return array($after, $before, $map); - } - -} diff --git a/src/applications/chatlog/controller/PhabricatorChatLogController.php b/src/applications/chatlog/controller/PhabricatorChatLogController.php deleted file mode 100644 index 64fcbf20bb..0000000000 --- a/src/applications/chatlog/controller/PhabricatorChatLogController.php +++ /dev/null @@ -1,3 +0,0 @@ -channels = $channels; - return $this; - } - - public function withIDs(array $channel_ids) { - $this->channelIDs = $channel_ids; - return $this; - } - - protected function loadPage() { - $table = new PhabricatorChatLogChannel(); - $conn_r = $table->establishConnection('r'); - - $data = queryfx_all( - $conn_r, - 'SELECT * FROM %T c %Q %Q %Q', - $table->getTableName(), - $this->buildWhereClause($conn_r), - $this->buildOrderClause($conn_r), - $this->buildLimitClause($conn_r)); - - $logs = $table->loadAllFromArray($data); - - return $logs; - } - - protected function buildWhereClause(AphrontDatabaseConnection $conn) { - $where = array(); - - $where[] = $this->buildPagingClause($conn); - - if ($this->channelIDs) { - $where[] = qsprintf( - $conn, - 'id IN (%Ld)', - $this->channelIDs); - - } - - if ($this->channels) { - $where[] = qsprintf( - $conn, - 'channelName IN (%Ls)', - $this->channels); - } - - return $this->formatWhereClause($conn, $where); - } - - public function getQueryApplicationClass() { - return 'PhabricatorChatLogApplication'; - } - -} diff --git a/src/applications/chatlog/query/PhabricatorChatLogQuery.php b/src/applications/chatlog/query/PhabricatorChatLogQuery.php deleted file mode 100644 index 88cf6da7e3..0000000000 --- a/src/applications/chatlog/query/PhabricatorChatLogQuery.php +++ /dev/null @@ -1,84 +0,0 @@ -channelIDs = $channel_ids; - return $this; - } - - public function withMaximumEpoch($epoch) { - $this->maximumEpoch = $epoch; - return $this; - } - - protected function loadPage() { - $table = new PhabricatorChatLogEvent(); - $conn_r = $table->establishConnection('r'); - - $data = queryfx_all( - $conn_r, - 'SELECT * FROM %T e %Q %Q %Q', - $table->getTableName(), - $this->buildWhereClause($conn_r), - $this->buildOrderClause($conn_r), - $this->buildLimitClause($conn_r)); - - $logs = $table->loadAllFromArray($data); - - return $logs; - } - - protected function willFilterPage(array $events) { - $channel_ids = mpull($events, 'getChannelID', 'getChannelID'); - - $channels = id(new PhabricatorChatLogChannelQuery()) - ->setViewer($this->getViewer()) - ->withIDs($channel_ids) - ->execute(); - $channels = mpull($channels, null, 'getID'); - - foreach ($events as $key => $event) { - $channel = idx($channels, $event->getChannelID()); - if (!$channel) { - unset($events[$key]); - continue; - } - - $event->attachChannel($channel); - } - - return $events; - } - - protected function buildWhereClause(AphrontDatabaseConnection $conn) { - $where = array(); - - $where[] = $this->buildPagingClause($conn); - - if ($this->maximumEpoch !== null) { - $where[] = qsprintf( - $conn, - 'epoch <= %d', - $this->maximumEpoch); - } - - if ($this->channelIDs !== null) { - $where[] = qsprintf( - $conn, - 'channelID IN (%Ld)', - $this->channelIDs); - } - - return $this->formatWhereClause($conn, $where); - } - - public function getQueryApplicationClass() { - return 'PhabricatorChatLogApplication'; - } - -} diff --git a/src/applications/chatlog/storage/PhabricatorChatLogChannel.php b/src/applications/chatlog/storage/PhabricatorChatLogChannel.php deleted file mode 100644 index 2e62bcb6cf..0000000000 --- a/src/applications/chatlog/storage/PhabricatorChatLogChannel.php +++ /dev/null @@ -1,51 +0,0 @@ - array( - 'serviceName' => 'text64', - 'serviceType' => 'text32', - 'channelName' => 'text64', - ), - self::CONFIG_KEY_SCHEMA => array( - 'key_channel' => array( - 'columns' => array('channelName', 'serviceType', 'serviceName'), - 'unique' => true, - ), - ), - ) + parent::getConfiguration(); - } - - public function getCapabilities() { - return array( - PhabricatorPolicyCapability::CAN_VIEW, - PhabricatorPolicyCapability::CAN_EDIT, - ); - } - - public function getPolicy($capability) { - switch ($capability) { - case PhabricatorPolicyCapability::CAN_VIEW: - return $this->viewPolicy; - break; - case PhabricatorPolicyCapability::CAN_EDIT: - return $this->editPolicy; - break; - } - } - - public function hasAutomaticCapability($capability, PhabricatorUser $viewer) { - return false; - } - -} diff --git a/src/applications/chatlog/storage/PhabricatorChatLogDAO.php b/src/applications/chatlog/storage/PhabricatorChatLogDAO.php deleted file mode 100644 index 8014168814..0000000000 --- a/src/applications/chatlog/storage/PhabricatorChatLogDAO.php +++ /dev/null @@ -1,9 +0,0 @@ - false, - self::CONFIG_COLUMN_SCHEMA => array( - 'author' => 'text64', - 'type' => 'text4', - 'message' => 'text', - ), - self::CONFIG_KEY_SCHEMA => array( - 'channel' => array( - 'columns' => array('epoch'), - ), - ), - ) + parent::getConfiguration(); - } - - public function attachChannel(PhabricatorChatLogChannel $channel) { - $this->channel = $channel; - return $this; - } - - public function getChannel() { - return $this->assertAttached($this->channel); - } - - -/* -( PhabricatorPolicyInterface )----------------------------------------- */ - - - public function getCapabilities() { - return array( - PhabricatorPolicyCapability::CAN_VIEW, - ); - } - - public function getPolicy($capability) { - return $this->getChannel()->getPolicy($capability); - } - - public function hasAutomaticCapability($capability, PhabricatorUser $viewer) { - return $this->getChannel()->hasAutomaticCapability($capability, $viewer); - } - -} diff --git a/src/docs/book/phorge.book b/src/docs/book/phorge.book index 0be0d5526d..b421144f2e 100644 --- a/src/docs/book/phorge.book +++ b/src/docs/book/phorge.book @@ -57,10 +57,6 @@ "name": "Celerity", "include": "(^src/applications/celerity/)" }, - "chatlog": { - "name": "Chatlog", - "include": "(^src/applications/chatlog/)" - }, "conduit": { "name": "Conduit", "include": "(^src/applications/conduit/)" diff --git a/src/infrastructure/storage/patch/PhabricatorBuiltinPatchList.php b/src/infrastructure/storage/patch/PhabricatorBuiltinPatchList.php index f68635860a..d29e1bcc07 100644 --- a/src/infrastructure/storage/patch/PhabricatorBuiltinPatchList.php +++ b/src/infrastructure/storage/patch/PhabricatorBuiltinPatchList.php @@ -50,7 +50,6 @@ final class PhabricatorBuiltinPatchList extends PhabricatorSQLPatchList { 'after' => array( /* First Patch */ ), ), 'db.calendar' => array(), - 'db.chatlog' => array(), 'db.conduit' => array(), 'db.countdown' => array(), 'db.daemon' => array(), diff --git a/webroot/rsrc/css/application/chatlog/chatlog.css b/webroot/rsrc/css/application/chatlog/chatlog.css deleted file mode 100644 index b0cb05a0e8..0000000000 --- a/webroot/rsrc/css/application/chatlog/chatlog.css +++ /dev/null @@ -1,81 +0,0 @@ -/** - * @provides phabricator-chatlog-css - */ - -.device-phone .phabricator-chat-log-wrap { - padding: 0; -} - -.phabricator-chat-log-pager-bottom { - padding: 8px 4px 16px; - font-weight: bold; - float: right; -} - -.phabricator-chat-log-pager-bottom a { - padding: 2px 3px; -} - -.phabricator-chat-log-panel { - clear: both; -} - -.phabricator-chat-log { - width: 100%; -} - -.phabricator-chat-log td { - padding: 8px; - line-height: 18px; -} - -.phabricator-chat-log tr { - background: #fff; -} - -.phabricator-chat-log tr td.author { - background: {$greybackground}; -} - -.phabricator-chat-log tr.alternate { - border-top: 1px solid {$thinblueborder}; - border-bottom: 1px solid {$thinblueborder}; -} - -.phabricator-chat-log tr.alternate td.author { - background: {$lightgreybackground}; -} - -.phabricator-chat-log tr.highlight td { - background: {$lightyellow}; -} - -.phabricator-chat-log td.timestamp { - white-space: nowrap; - text-align: right; - width: 12em; -} - -.phabricator-chat-log td.message .timestamp { - color: {$bluetext}; - font-size: {$smallestfontsize}; - float: right; - margin-left: 5px; -} - -.phabricator-chat-log td.author { - white-space: nowrap; - text-align: right; - font-weight: bold; - width: 140px; - color: {$darkbluetext}; -} - -.device-phone .phabricator-chat-log td.author { - width: 80px; -} - -.phabricator-chat-log td.message { - white-space: pre-wrap; - word-break: break-word; -} From c3850a3c1530fa2d52c81ad35de4f0a6e12459a9 Mon Sep 17 00:00:00 2001 From: Andre Klapper Date: Tue, 28 Nov 2023 13:46:37 +0100 Subject: [PATCH 84/93] Fix PHP 8.1 "strlen(null)" exception removing custom alt text from image file Summary: `strlen()` was used in Phabricator to check if a generic value is a non-empty string. This behavior is deprecated since PHP 8.1. Phorge adopts `phutil_nonempty_string()` as a replacement. Note: this may highlight other absurd input values that might be worth correcting instead of just ignoring. If phutil_nonempty_string() throws an exception in your instance, report it to Phorge to evaluate and fix that specific corner case. ``` ERROR 8192: strlen(): Passing null to parameter #1 ($string) of type string is deprecated at [/var/www/html/phorge/phorge/src/applications/files/xaction/PhabricatorFileAltTextTransaction.php:59] ``` Closes T15678 Test Plan: Add and remove alt text on an image file; then go to `/feed/query/all/` Reviewers: O1 Blessed Committers, speck Reviewed By: O1 Blessed Committers, speck Subscribers: tobiaswiese, valerio.bozzolan, Matthew, Cigaryno Maniphest Tasks: T15678 Differential Revision: https://we.phorge.it/D25481 --- .../files/xaction/PhabricatorFileAltTextTransaction.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/applications/files/xaction/PhabricatorFileAltTextTransaction.php b/src/applications/files/xaction/PhabricatorFileAltTextTransaction.php index c3151910e4..063a599170 100644 --- a/src/applications/files/xaction/PhabricatorFileAltTextTransaction.php +++ b/src/applications/files/xaction/PhabricatorFileAltTextTransaction.php @@ -50,13 +50,13 @@ final class PhabricatorFileAltTextTransaction $old_value = $this->getOldValue(); $new_value = $this->getNewValue(); - if (!strlen($old_value)) { + if (!phutil_nonempty_string($old_value)) { return pht( '%s set the alternate text for %s to %s.', $this->renderAuthor(), $this->renderObject(), $this->renderNewValue()); - } else if (!strlen($new_value)) { + } else if (!phutil_nonempty_string($new_value)) { return pht( '%s removed the alternate text for %s (was %s).', $this->renderAuthor(), From 99ee9357eff29f450526607cabec9ec557cfdec3 Mon Sep 17 00:00:00 2001 From: Christopher Speck Date: Thu, 30 Nov 2023 20:15:50 -0500 Subject: [PATCH 85/93] Updates for Mercurial's HTTP protocol Summary: While testing https://secure.phabricator.com/D21864 I ran into some issues getting mercurial HTTP access working. Using wireshark I confirmed that my local mercurial 6.4 was not including command arguments as HTTP headers but in the querystring. I didn't dig too deep into understanding when/why this started happening. The protocol documents this in [[ https://repo.mercurial-scm.org/hg/file/tip/mercurial/helptext/internals/wireprotocol.txt | wireprotocol.txt ]]. >Command arguments can be sent multiple ways. The simplest is part of the URL query string using ``x-www-form-urlencoded`` encoding (see Python's ``urllib.urlencode()``. However, many servers impose length limitations on the URL. So this mechanism is typically only used if the server doesn't support other mechanisms. Based on that either the mercurial on the server is really old (it's 6.1.1 tho) or maybe some other parsing/info passing in Phab's handling of the wire protocol is causing the client to downgrade the wire protocol support. Cherry-picked from: https://secure.phabricator.com/D21867 https://secure.phabricator.com/rP0b6e758978a9691bd5ad25db4aa4c4301640a9a9 Test Plan: Host mercurial repo using HTTP, test push/pull. Reviewers: O1 Blessed Committers, valerio.bozzolan Reviewed By: O1 Blessed Committers, valerio.bozzolan Subscribers: tobiaswiese, Matthew, Cigaryno Differential Revision: https://we.phorge.it/D25471 --- .../controller/DiffusionServeController.php | 25 ++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/src/applications/diffusion/controller/DiffusionServeController.php b/src/applications/diffusion/controller/DiffusionServeController.php index 93656ea607..d092f9740d 100644 --- a/src/applications/diffusion/controller/DiffusionServeController.php +++ b/src/applications/diffusion/controller/DiffusionServeController.php @@ -878,10 +878,29 @@ final class DiffusionServeController extends DiffusionController { } $args_raw[] = $_SERVER[$header]; } - $args_raw = implode('', $args_raw); - return id(new PhutilQueryStringParser()) - ->parseQueryString($args_raw); + if ($args_raw) { + $args_raw = implode('', $args_raw); + return id(new PhutilQueryStringParser()) + ->parseQueryString($args_raw); + } + + // Sometimes arguments come in via the query string. Note that this will + // not handle multi-value entries e.g. "a[]=1,a[]=2" however it's unclear + // whether or how the mercurial protocol should handle this. + $query = idx($_SERVER, 'QUERY_STRING', ''); + $query_pairs = id(new PhutilQueryStringParser()) + ->parseQueryString($query); + foreach ($query_pairs as $key => $value) { + // Filter out private/internal keys as well as the command itself. + if (strncmp($key, '__', 2) && $key != 'cmd') { + $args_raw[$key] = $value; + } + } + + // TODO: Arguments can also come in via request body for POST requests. The + // body would be all arguments, url-encoded. + return $args_raw; } private function formatMercurialArguments($command, array $arguments) { From acedbd022d45e34bbb6abbe303f0b97dd6f36e4d Mon Sep 17 00:00:00 2001 From: Andre Klapper Date: Mon, 4 Dec 2023 19:31:39 -0800 Subject: [PATCH 86/93] Fix exception in Transaction Log after renaming Pholio Mock image: Call to undefined method PholioImageSequenceTransaction::renderHandleLink() Summary: Replace call to undefined `renderHandleLink()` with `renderHandle()`. Additionally, pass `head_key($new)` instead of `key($new)`. This might not be needed strictly speaking for this very issue but should not harm either as several images in a mock can be renamed at once. ``` EXCEPTION: (Error) Call to undefined method PholioImageSequenceTransaction::renderHandleLink() at [/src/applications/pholio/xaction/PholioImageSequenceTransaction.php:32] ``` Closes T15680 Test Plan: * Rename the title of an image in a Pholio mock. * Go to `/feed/transactions/query/all/` which now renders instead of showing an error, and shows two entries: * `user renamed an image (newname.jpg) from oldname.jpg to newname.jpg.` and `user updated an image's (newname.jpg) sequence.` (However, separate T15679 will still show up in the error log after this change.) Reviewers: O1 Blessed Committers, speck Reviewed By: O1 Blessed Committers, speck Subscribers: speck, tobiaswiese, valerio.bozzolan, Matthew, Cigaryno Maniphest Tasks: T15680 Differential Revision: https://we.phorge.it/D25482 --- .../pholio/xaction/PholioImageSequenceTransaction.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/applications/pholio/xaction/PholioImageSequenceTransaction.php b/src/applications/pholio/xaction/PholioImageSequenceTransaction.php index c98c199adf..4d6099ed14 100644 --- a/src/applications/pholio/xaction/PholioImageSequenceTransaction.php +++ b/src/applications/pholio/xaction/PholioImageSequenceTransaction.php @@ -29,7 +29,7 @@ final class PholioImageSequenceTransaction return pht( '%s updated an image\'s (%s) sequence.', $this->renderAuthor(), - $this->renderHandleLink(key($new))); + $this->renderHandle(head_key($new))); } public function getTitleForFeed() { From e610e739cb4294dcab92c3145285a5ffa5c3cf61 Mon Sep 17 00:00:00 2001 From: Andre Klapper Date: Tue, 5 Dec 2023 10:23:43 -0800 Subject: [PATCH 87/93] Fix PHP 8.1 exceptions rendering task when custom select field configured Summary: `strlen()` was used in Phabricator to check if a generic value is a non-empty string. This behavior is deprecated since PHP 8.1. Phorge adopts `phutil_nonempty_string()` as a replacement. Note: this may highlight other absurd input values that might be worth correcting instead of just ignoring. If phutil_nonempty_string() throws an exception in your instance, report it to Phorge to evaluate and fix that specific corner case. In the other case, do not call `json_decode()` when passing null to it. ``` EXCEPTION: (RuntimeException) json_decode(): Passing null to parameter #1 ($json) of type string is deprecated at [/src/error/PhutilErrorHandler.php:261] #0 <#2> PhutilErrorHandler::handleError(integer, string, string, integer) called at [/src/error/PhutilErrorHandler.php:261] #1 <#2> json_decode(NULL, boolean) called at [/src/infrastructure/customfield/standard/PhabricatorStandardCustomFieldPHIDs.php:44] ``` ``` EXCEPTION: (RuntimeException) strlen(): Passing null to parameter #1 ($string) of type string is deprecated at [/src/error/PhutilErrorHandler.php:261] #0 <#2> PhutilErrorHandler::handleError(integer, string, string, integer) called at [/src/infrastructure/customfield/standard/PhabricatorStandardCustomFieldSelect.php:76] ``` Closes T15683 Test Plan: After configuring a custom `select` field, access a task. Reviewers: O1 Blessed Committers, speck Reviewed By: O1 Blessed Committers, speck Subscribers: tobiaswiese, valerio.bozzolan, Matthew, Cigaryno Maniphest Tasks: T15683 Differential Revision: https://we.phorge.it/D25487 --- .../standard/PhabricatorStandardCustomFieldPHIDs.php | 2 +- .../standard/PhabricatorStandardCustomFieldSelect.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/infrastructure/customfield/standard/PhabricatorStandardCustomFieldPHIDs.php b/src/infrastructure/customfield/standard/PhabricatorStandardCustomFieldPHIDs.php index a96ebefda1..48d5ea725a 100644 --- a/src/infrastructure/customfield/standard/PhabricatorStandardCustomFieldPHIDs.php +++ b/src/infrastructure/customfield/standard/PhabricatorStandardCustomFieldPHIDs.php @@ -40,7 +40,7 @@ abstract class PhabricatorStandardCustomFieldPHIDs // TODO: Clean this up. $result = array(); - if (!is_array($value)) { + if (!is_array($value) && phutil_nonempty_string($value)) { $value = json_decode($value, true); if (is_array($value)) { $result = array_values($value); diff --git a/src/infrastructure/customfield/standard/PhabricatorStandardCustomFieldSelect.php b/src/infrastructure/customfield/standard/PhabricatorStandardCustomFieldSelect.php index 5957afe56a..12e0aa6c3d 100644 --- a/src/infrastructure/customfield/standard/PhabricatorStandardCustomFieldSelect.php +++ b/src/infrastructure/customfield/standard/PhabricatorStandardCustomFieldSelect.php @@ -73,7 +73,7 @@ final class PhabricatorStandardCustomFieldSelect } public function renderPropertyViewValue(array $handles) { - if (!strlen($this->getFieldValue())) { + if (!phutil_nonempty_string($this->getFieldValue())) { return null; } return idx($this->getOptions(), $this->getFieldValue()); From e59702569f8e7076952defa683452d293fa5d44a Mon Sep 17 00:00:00 2001 From: Waldir Pimenta Date: Wed, 6 Dec 2023 15:35:05 +0000 Subject: [PATCH 88/93] CSS adjustments to Conpherence Summary: **Fix Conpherence messages overlapping header in mobile mode** Before: {F413544} After: {F413546} **Make Conpherence input box be one line even in desktop mode** Before: {F413541} After: {F413540} This second change, in particular, is motivated by the fact that pressing `Enter` sends the message, whereas the multi-line box gives the impression that the `Enter` key would simply introduce a line break in the message. (That's still possible via `Shift`+`Enter`, btw.) Test Plan: - Visit a Conpherence room with some content in mobile mode; scroll down and notice that the messages no longer slightly overlap the header. - Visit a Conpherence room in desktop mode; verify that the input box now has the height of a single line. Reviewers: O1 Blessed Committers, valerio.bozzolan Reviewed By: O1 Blessed Committers, valerio.bozzolan Subscribers: speck, tobiaswiese, valerio.bozzolan, Matthew, Cigaryno Tags: #conpherence Differential Revision: https://we.phorge.it/D25485 --- resources/celerity/map.php | 6 +++--- .../rsrc/css/application/conpherence/message-pane.css | 11 +++++------ 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/resources/celerity/map.php b/resources/celerity/map.php index 5fc371bcf0..d0bb7523a7 100644 --- a/resources/celerity/map.php +++ b/resources/celerity/map.php @@ -7,7 +7,7 @@ */ return array( 'names' => array( - 'conpherence.pkg.css' => '76ed87e3', + 'conpherence.pkg.css' => '2f25eb4f', 'conpherence.pkg.js' => '020aebcf', 'core.pkg.css' => 'c0bdb5b4', 'core.pkg.js' => '2eeda9e0', @@ -51,7 +51,7 @@ return array( 'rsrc/css/application/conpherence/durable-column.css' => '2d57072b', 'rsrc/css/application/conpherence/header-pane.css' => 'c9a3db8e', 'rsrc/css/application/conpherence/menu.css' => '67f4680d', - 'rsrc/css/application/conpherence/message-pane.css' => 'd244db1e', + 'rsrc/css/application/conpherence/message-pane.css' => '50b1345e', 'rsrc/css/application/conpherence/notification.css' => '85c48def', 'rsrc/css/application/conpherence/participant-pane.css' => '69e0058a', 'rsrc/css/application/conpherence/transaction.css' => '3a3f5e7e', @@ -552,7 +552,7 @@ return array( 'conpherence-durable-column-view' => '2d57072b', 'conpherence-header-pane-css' => 'c9a3db8e', 'conpherence-menu-css' => '67f4680d', - 'conpherence-message-pane-css' => 'd244db1e', + 'conpherence-message-pane-css' => '50b1345e', 'conpherence-notification-css' => '85c48def', 'conpherence-participant-pane-css' => '69e0058a', 'conpherence-thread-manager' => 'aec8e38c', diff --git a/webroot/rsrc/css/application/conpherence/message-pane.css b/webroot/rsrc/css/application/conpherence/message-pane.css index 0dc33789f3..87be9c5897 100644 --- a/webroot/rsrc/css/application/conpherence/message-pane.css +++ b/webroot/rsrc/css/application/conpherence/message-pane.css @@ -9,7 +9,7 @@ position: fixed; left: 240px; right: 240px; - top: 106px; + top: 115px; bottom: 0px; min-width: 300px; width: auto; @@ -55,8 +55,8 @@ position: fixed; left: 240px; right: 240px; - top: 106px; - bottom: 142px; + top: 115px; + bottom: 88px; overflow-x: hidden; overflow-y: auto; -webkit-overflow-scrolling: touch; @@ -95,7 +95,7 @@ .conpherence-message-pane .phui-form-view { border-width: 0; - height: 130px; + height: 76px; padding: 0 20px 12px; position: fixed; bottom: 0; @@ -347,7 +347,7 @@ body .conpherence-message-pane .aphront-form-control { } .conpherence-message-pane .remarkup-assist-textarea { - height: 88px; + height: 34px; padding: 8px; box-sizing: border-box; -moz-box-sizing: border-box; @@ -360,7 +360,6 @@ body .conpherence-message-pane .aphront-form-control { margin: 0; padding: 7px 8px 6px 38px; width: 100%; - height: 34px; resize: none; border-color: {$greyborder}; border-top-left-radius: 3px; From c8a927006067ea87f0ccb968006b162b98c5d0b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bartosz=20Dziewo=C5=84ski?= Date: Wed, 6 Dec 2023 16:50:35 +0100 Subject: [PATCH 89/93] Use user's preferred font for inline code snippets too MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Summary: Use user's preferred font for inline code snippets, like we already do for block code snippets. Test Plan: Set a non-default font in Settings → Display Preferences → Monospaced Font. Make sure that it applies to both single-tick (inline) and triple-tick (block) code snippets in comments. For example, enter: 42px Tahoma Reviewers: O1 Blessed Committers, valerio.bozzolan Reviewed By: O1 Blessed Committers, valerio.bozzolan Subscribers: tobiaswiese, valerio.bozzolan, Matthew, Cigaryno Maniphest Tasks: T15682 Differential Revision: https://we.phorge.it/D25486 --- src/view/page/PhabricatorStandardPageView.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/view/page/PhabricatorStandardPageView.php b/src/view/page/PhabricatorStandardPageView.php index a81820de3c..005ede23a7 100644 --- a/src/view/page/PhabricatorStandardPageView.php +++ b/src/view/page/PhabricatorStandardPageView.php @@ -413,8 +413,9 @@ final class PhabricatorStandardPageView extends PhabricatorBarePageView $font_css = hsprintf( '', $monospaced); } From 5ddca7da55e3f94c489f20f39b50a45d169fe6cb Mon Sep 17 00:00:00 2001 From: Andre Klapper Date: Wed, 6 Dec 2023 10:29:32 -0800 Subject: [PATCH 90/93] Fix PHP 8.1 "strlen(null)" exception rendering dashboard panel with latest tasks when custom text field configured Summary: `strlen()` was used in Phabricator to check if a generic value is a non-empty string. This behavior is deprecated since PHP 8.1. Phorge adopts `phutil_nonempty_string()` as a replacement. Note: this may highlight other absurd input values that might be worth correcting instead of just ignoring. If phutil_nonempty_string() throws an exception in your instance, report it to Phorge to evaluate and fix that specific corner case. ``` EXCEPTION: (RuntimeException) strlen(): Passing null to parameter #1 ($string) of type string is deprecated at [/src/error/PhutilErrorHandler.php:261] #0 <#2> PhutilErrorHandler::handleError(integer, string, string, integer) called at [/src/infrastructure/customfield/standard/PhabricatorStandardCustomFieldText.php:33] ``` Closes T15684 Test Plan: After configuring a custom `text` field and a dashboard panel to query and listed the latest created tasks, access the panel. Reviewers: O1 Blessed Committers, valerio.bozzolan Reviewed By: O1 Blessed Committers, valerio.bozzolan Subscribers: tobiaswiese, valerio.bozzolan, Matthew, Cigaryno Maniphest Tasks: T15684 Differential Revision: https://we.phorge.it/D25488 --- .../standard/PhabricatorStandardCustomFieldText.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/infrastructure/customfield/standard/PhabricatorStandardCustomFieldText.php b/src/infrastructure/customfield/standard/PhabricatorStandardCustomFieldText.php index 56164bb7b5..758c50e817 100644 --- a/src/infrastructure/customfield/standard/PhabricatorStandardCustomFieldText.php +++ b/src/infrastructure/customfield/standard/PhabricatorStandardCustomFieldText.php @@ -11,7 +11,7 @@ final class PhabricatorStandardCustomFieldText $indexes = array(); $value = $this->getFieldValue(); - if (strlen($value)) { + if (phutil_nonempty_string($value)) { $indexes[] = $this->newStringIndex($value); } @@ -30,7 +30,7 @@ final class PhabricatorStandardCustomFieldText PhabricatorCursorPagedPolicyAwareQuery $query, $value) { - if (strlen($value)) { + if (phutil_nonempty_string($value)) { $query->withApplicationSearchContainsConstraint( $this->newStringIndex(null), $value); From 6c8329fb661483b5178f66d293f605ffe1ea35fc Mon Sep 17 00:00:00 2001 From: Mukunda Modell Date: Tue, 5 Dec 2023 06:56:11 -0800 Subject: [PATCH 91/93] Include 'published' date of posts in Phame Atom feeds Summary: Metadata of Phame blog posts includes the 'updated' date of a blog post. Make them also include the original 'published' date. Patch written by @20after4 from: https://phabricator.wikimedia.org/rPHAB3de500bfc845759d6da82180df0adfc12f973463 Closes T15686 Test Plan: * Go to the Atom feed of blog 1 at `/phame/blog/feed/1/` and look at this ``'s source * Apply patch and do the same, see additional `` entry just like the `` * Edit the last blog post in blog 1, then check Atom feed and verify that the published and updated date stamp differ as expected Reviewers: O1 Blessed Committers, valerio.bozzolan Reviewed By: O1 Blessed Committers, valerio.bozzolan Subscribers: tobiaswiese, valerio.bozzolan, Matthew, 20after4, Cigaryno Maniphest Tasks: T15686 Differential Revision: https://we.phorge.it/D25490 --- .../phame/controller/blog/PhameBlogFeedController.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/applications/phame/controller/blog/PhameBlogFeedController.php b/src/applications/phame/controller/blog/PhameBlogFeedController.php index c0c6e60cc4..1523a8d5e6 100644 --- a/src/applications/phame/controller/blog/PhameBlogFeedController.php +++ b/src/applications/phame/controller/blog/PhameBlogFeedController.php @@ -71,6 +71,11 @@ final class PhameBlogFeedController extends PhameBlogController { '%s', $bloggers[$post->getBloggerPHID()]->getFullName()); + $content[] = phutil_tag( + 'published', + array(), + date('c', $post->getDatePublished())); + $content[] = phutil_tag( 'updated', array(), From c49eeb235ea0276dc34e9f87404b696642495f5a Mon Sep 17 00:00:00 2001 From: Waldir Pimenta Date: Thu, 7 Dec 2023 16:21:39 +0000 Subject: [PATCH 92/93] Improve command line prompts in setup issue pages MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Summary: This is a follow-up to D25425, where these improvements to the CLI prompt markers were discussed. Changes included in this revision: - Build all prompts the same way - Remove space after the prompt marker (add it via CSS instead) - Add server path prefix - Make the prompt unselectable Test Plan: - Visit any of the setup issue pages, e.g. /config/issue/auth.config-unlocked/ (after ensuring that the corresponding issue is present — in this case, by doing `./bin/auth unlock`) - For example, Deactivate all PHP extensions to trigger each /config/issue/extension.gd/ etc. - For example, update at least up to `dc10a7e69ea3` to see the database upgrade tip etc. - Confirm that the command line prompts now include the path prefix - Confirm that selecting the command via double-click (or click-and-drag) does not select the prompt Reviewers: O1 Blessed Committers, valerio.bozzolan Reviewed By: O1 Blessed Committers, valerio.bozzolan Subscribers: tobiaswiese, valerio.bozzolan, Matthew, Cigaryno Tags: #ux, #config Differential Revision: https://we.phorge.it/D25466 --- resources/celerity/map.php | 4 ++-- .../config/check/PhabricatorAuthSetupCheck.php | 3 ++- .../config/check/PhabricatorBaseURISetupCheck.php | 7 +++---- .../config/check/PhabricatorDaemonsSetupCheck.php | 10 ++++++++-- .../check/PhabricatorDatabaseSetupCheck.php | 15 +++++++++++---- .../check/PhabricatorElasticsearchSetupCheck.php | 10 ++++++++-- .../check/PhabricatorExtraConfigSetupCheck.php | 14 ++++++++++---- .../config/view/PhabricatorSetupIssueView.php | 9 +++++---- .../examples/PhabricatorSetupIssueUIExample.php | 8 ++++++-- .../rsrc/css/application/config/setup-issue.css | 5 +++++ 10 files changed, 60 insertions(+), 25 deletions(-) diff --git a/resources/celerity/map.php b/resources/celerity/map.php index d0bb7523a7..12ad67b011 100644 --- a/resources/celerity/map.php +++ b/resources/celerity/map.php @@ -45,7 +45,7 @@ return array( 'rsrc/css/application/conduit/conduit-api.css' => 'ce2cfc41', 'rsrc/css/application/config/config-options.css' => '16c920ae', 'rsrc/css/application/config/config-template.css' => 'e689dbbd', - 'rsrc/css/application/config/setup-issue.css' => '5eed85b2', + 'rsrc/css/application/config/setup-issue.css' => '93231115', 'rsrc/css/application/config/unhandled-exception.css' => '9ecfc00d', 'rsrc/css/application/conpherence/color.css' => 'b17746b0', 'rsrc/css/application/conpherence/durable-column.css' => '2d57072b', @@ -903,7 +903,7 @@ return array( 'project-card-view-css' => 'c1200da7', 'project-triggers-css' => 'cd9c8bb9', 'project-view-css' => '2f7caa20', - 'setup-issue-css' => '5eed85b2', + 'setup-issue-css' => '93231115', 'sprite-login-css' => '07052ee0', 'sprite-tokens-css' => 'f1896dc5', 'syntax-default-css' => '055fc231', diff --git a/src/applications/config/check/PhabricatorAuthSetupCheck.php b/src/applications/config/check/PhabricatorAuthSetupCheck.php index b971404c38..8705047263 100644 --- a/src/applications/config/check/PhabricatorAuthSetupCheck.php +++ b/src/applications/config/check/PhabricatorAuthSetupCheck.php @@ -74,7 +74,8 @@ final class PhabricatorAuthSetupCheck extends PhabricatorSetupCheck { ->addRelatedPhabricatorConfig('auth.lock-config') ->addCommand( hsprintf( - '$ ./bin/auth lock')); + '%s $./bin/auth lock', + PlatformSymbols::getPlatformServerPath())); } } } diff --git a/src/applications/config/check/PhabricatorBaseURISetupCheck.php b/src/applications/config/check/PhabricatorBaseURISetupCheck.php index 92e46641d7..e73c1455bf 100644 --- a/src/applications/config/check/PhabricatorBaseURISetupCheck.php +++ b/src/applications/config/check/PhabricatorBaseURISetupCheck.php @@ -96,9 +96,8 @@ final class PhabricatorBaseURISetupCheck extends PhabricatorSetupCheck { ->setMessage($message) ->addCommand( hsprintf( - '$ %s', - csprintf( - './bin/config set phabricator.base-uri %s', - $base_uri_guess))); + '%s $./bin/config set phabricator.base-uri %s', + PlatformSymbols::getPlatformServerPath(), + $base_uri_guess)); } } diff --git a/src/applications/config/check/PhabricatorDaemonsSetupCheck.php b/src/applications/config/check/PhabricatorDaemonsSetupCheck.php index df5821665c..ceedd5137e 100644 --- a/src/applications/config/check/PhabricatorDaemonsSetupCheck.php +++ b/src/applications/config/check/PhabricatorDaemonsSetupCheck.php @@ -49,7 +49,10 @@ final class PhabricatorDaemonsSetupCheck extends PhabricatorSetupCheck { ->setName(pht('Daemons Are Not Running')) ->setSummary($summary) ->setMessage($message) - ->addCommand('$ ./bin/phd start'); + ->addCommand( + hsprintf( + '%s $./bin/phd start', + PlatformSymbols::getPlatformServerPath())); } $expect_user = PhabricatorEnv::getEnvConfig('phd.user'); @@ -90,7 +93,10 @@ final class PhabricatorDaemonsSetupCheck extends PhabricatorSetupCheck { ->setSummary($summary) ->setMessage($message) ->addPhabricatorConfig('phd.user') - ->addCommand('$ ./bin/phd restart'); + ->addCommand( + hsprintf( + '%s $./bin/phd restart', + PlatformSymbols::getPlatformServerPath())); break; } diff --git a/src/applications/config/check/PhabricatorDatabaseSetupCheck.php b/src/applications/config/check/PhabricatorDatabaseSetupCheck.php index d3f6d52f04..99815d85e6 100644 --- a/src/applications/config/check/PhabricatorDatabaseSetupCheck.php +++ b/src/applications/config/check/PhabricatorDatabaseSetupCheck.php @@ -35,11 +35,13 @@ final class PhabricatorDatabaseSetupCheck extends PhabricatorSetupCheck { ->addPhabricatorConfig('mysql.port') ->addCommand( hsprintf( - '$ ./bin/config set mysql.host %s', + '%s $./bin/config set mysql.host %s', + PlatformSymbols::getPlatformServerPath(), $host)) ->addCommand( hsprintf( - '$ ./bin/config set mysql.port %s', + '%s $./bin/config set mysql.port %s', + PlatformSymbols::getPlatformServerPath(), $port)); } @@ -134,7 +136,10 @@ final class PhabricatorDatabaseSetupCheck extends PhabricatorSetupCheck { ->setName(pht('Setup MySQL Schema')) ->setMessage($message) ->setIsFatal(true) - ->addCommand(hsprintf('$ ./bin/storage upgrade')); + ->addCommand( + hsprintf( + '%s $./bin/storage upgrade', + PlatformSymbols::getPlatformServerPath())); return true; } @@ -160,7 +165,9 @@ final class PhabricatorDatabaseSetupCheck extends PhabricatorSetupCheck { ->setIsFatal(true) ->setMessage($message) ->addCommand( - hsprintf('$ ./bin/storage upgrade')); + hsprintf( + '%s $./bin/storage upgrade', + PlatformSymbols::getPlatformServerPath())); return true; } diff --git a/src/applications/config/check/PhabricatorElasticsearchSetupCheck.php b/src/applications/config/check/PhabricatorElasticsearchSetupCheck.php index 8466c5a6c6..268f55f80b 100644 --- a/src/applications/config/check/PhabricatorElasticsearchSetupCheck.php +++ b/src/applications/config/check/PhabricatorElasticsearchSetupCheck.php @@ -60,7 +60,10 @@ final class PhabricatorElasticsearchSetupCheck extends PhabricatorSetupCheck { $this ->newIssue('elastic.missing-index') ->setName(pht('Elasticsearch Index Not Found')) - ->addCommand('./bin/search init') + ->addCommand( + hsprintf( + '%s $./bin/search init', + PlatformSymbols::getPlatformServerPath())) ->setSummary($summary) ->setMessage($message); @@ -76,7 +79,10 @@ final class PhabricatorElasticsearchSetupCheck extends PhabricatorSetupCheck { $this ->newIssue('elastic.broken-index') ->setName(pht('Elasticsearch Index Schema Mismatch')) - ->addCommand('./bin/search init') + ->addCommand( + hsprintf( + '%s $./bin/search init', + PlatformSymbols::getPlatformServerPath())) ->setSummary($summary) ->setMessage($message); } diff --git a/src/applications/config/check/PhabricatorExtraConfigSetupCheck.php b/src/applications/config/check/PhabricatorExtraConfigSetupCheck.php index ae14a0ab0a..070127ccbd 100644 --- a/src/applications/config/check/PhabricatorExtraConfigSetupCheck.php +++ b/src/applications/config/check/PhabricatorExtraConfigSetupCheck.php @@ -76,7 +76,10 @@ final class PhabricatorExtraConfigSetupCheck extends PhabricatorSetupCheck { $issue->setMessage($message); if ($found_local) { - $command = csprintf('$ ./bin/config delete %s', $key); + $command = hsprintf( + '%s $./bin/config delete %s', + PlatformSymbols::getPlatformServerPath(), + $key); $issue->addCommand($command); } @@ -166,9 +169,12 @@ final class PhabricatorExtraConfigSetupCheck extends PhabricatorSetupCheck { 'target' => '_blank', ), $doc_name)); - $command = csprintf( - '$ ./bin/config delete --database %R', - $key); + $command = hsprintf( + '%s $%s', + PlatformSymbols::getPlatformServerPath(), + csprintf( + './bin/config delete --database %R', + $key)); $this->newIssue('config.locked.'.$key) ->setShortName(pht('Deprecated Config Source')) diff --git a/src/applications/config/view/PhabricatorSetupIssueView.php b/src/applications/config/view/PhabricatorSetupIssueView.php index e07e33b3d0..9aff749bb2 100644 --- a/src/applications/config/view/PhabricatorSetupIssueView.php +++ b/src/applications/config/view/PhabricatorSetupIssueView.php @@ -83,11 +83,11 @@ final class PhabricatorSetupIssueView extends AphrontView { // TODO: We should do a better job of detecting how to install extensions // on the current system. $install_commands = hsprintf( - "\$ sudo apt-get install php-extname ". + "$sudo apt-get install php-extname ". "# Debian / Ubuntu\n". - "\$ sudo dnf install php-extname ". + "$sudo dnf install php-extname ". "# Red Hat / Derivatives\n". - "\$ sudo yum install php-extname ". + "$sudo yum install php-extname ". "# Older Red Hat versions"); $fallback_info = pht( @@ -286,7 +286,8 @@ final class PhabricatorSetupIssueView extends AphrontView { $update = array(); foreach ($configs as $key) { $update[] = hsprintf( - '$ ./bin/config set %s value', + '%s $./bin/config set %s value', + PlatformSymbols::getPlatformServerPath(), $key); } $update = phutil_tag('pre', array(), phutil_implode_html("\n", $update)); diff --git a/src/applications/uiexample/examples/PhabricatorSetupIssueUIExample.php b/src/applications/uiexample/examples/PhabricatorSetupIssueUIExample.php index d6386e59d4..4343bcb8cb 100644 --- a/src/applications/uiexample/examples/PhabricatorSetupIssueUIExample.php +++ b/src/applications/uiexample/examples/PhabricatorSetupIssueUIExample.php @@ -24,8 +24,12 @@ final class PhabricatorSetupIssueUIExample extends PhabricatorUIExample { ->setSummary(pht('Summary')) ->setMessage(pht('Message')) ->setIssueKey('example.key') - ->addCommand('$ # Add Command') - ->addCommand(hsprintf('$ %s', '$ ls -1 > /dev/null')) + ->addCommand(hsprintf( + '%s $# Add Command', + PlatformSymbols::getPlatformServerPath())) + ->addCommand(hsprintf( + '%s $ls -1 > /dev/null', + PlatformSymbols::getPlatformServerPath())) ->addPHPConfig('php.config.example') ->addPhabricatorConfig('test.value') ->addPHPExtension('libexample'); diff --git a/webroot/rsrc/css/application/config/setup-issue.css b/webroot/rsrc/css/application/config/setup-issue.css index a80b02815c..4af5e9f417 100644 --- a/webroot/rsrc/css/application/config/setup-issue.css +++ b/webroot/rsrc/css/application/config/setup-issue.css @@ -122,6 +122,11 @@ padding: 12px 0; } +.setup-issue-config > pre > tt { + user-select: none; + margin-right: 0.5em; +} + .setup-issue-config + .setup-issue-config { padding-top: 0; } From 2ba2cbaf9bbf8f88e910d3da0a3cd643e4879e8a Mon Sep 17 00:00:00 2001 From: Aviv Eyal Date: Fri, 8 Dec 2023 17:39:39 +0200 Subject: [PATCH 93/93] Show Deprecation Warnings as Setup Warnings Summary: Capture Deprecation Warnings, collect them into cache, and show them as a Setup Issue for admins to see and report back to us. This only captures a sample of the traces, so not to overwhelm users (and RAM. and us) with reports. Requires D25388. Refs T15554. Test Plan: Run some flows that are known to bring up Deprecation Warnings. See them as a Setup Issue! Click little triangles to see details. Reviewers: O1 Blessed Committers, Matthew Reviewed By: O1 Blessed Committers, Matthew Subscribers: revi, Sten, tobiaswiese, valerio.bozzolan, Matthew, Cigaryno Maniphest Tasks: T15554 Differential Revision: https://we.phorge.it/D25440 --- src/__phutil_library_map__.php | 4 + .../check/PhorgeCodeWarningSetupCheck.php | 81 +++++++++++++++++++ .../PhabricatorSystemApplication.php | 1 + ...PhorgeSystemDeprecationWarningListener.php | 58 +++++++++++++ 4 files changed, 144 insertions(+) create mode 100644 src/applications/config/check/PhorgeCodeWarningSetupCheck.php create mode 100644 src/applications/system/events/PhorgeSystemDeprecationWarningListener.php diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php index f2a39023e4..d22dc78970 100644 --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -5387,6 +5387,8 @@ phutil_register_library_map(array( 'PholioTransactionType' => 'applications/pholio/xaction/PholioTransactionType.php', 'PholioTransactionView' => 'applications/pholio/view/PholioTransactionView.php', 'PholioUploadedImageView' => 'applications/pholio/view/PholioUploadedImageView.php', + 'PhorgeCodeWarningSetupCheck' => 'applications/config/check/PhorgeCodeWarningSetupCheck.php', + 'PhorgeSystemDeprecationWarningListener' => 'applications/system/events/PhorgeSystemDeprecationWarningListener.php', 'PhortuneAccount' => 'applications/phortune/storage/PhortuneAccount.php', 'PhortuneAccountAddManagerController' => 'applications/phortune/controller/account/PhortuneAccountAddManagerController.php', 'PhortuneAccountBillingAddressTransaction' => 'applications/phortune/xaction/PhortuneAccountBillingAddressTransaction.php', @@ -12208,6 +12210,8 @@ phutil_register_library_map(array( 'PholioTransactionType' => 'PhabricatorModularTransactionType', 'PholioTransactionView' => 'PhabricatorApplicationTransactionView', 'PholioUploadedImageView' => 'AphrontView', + 'PhorgeCodeWarningSetupCheck' => 'PhabricatorSetupCheck', + 'PhorgeSystemDeprecationWarningListener' => 'PhabricatorEventListener', 'PhortuneAccount' => array( 'PhortuneDAO', 'PhabricatorApplicationTransactionInterface', diff --git a/src/applications/config/check/PhorgeCodeWarningSetupCheck.php b/src/applications/config/check/PhorgeCodeWarningSetupCheck.php new file mode 100644 index 0000000000..2aaf33ac25 --- /dev/null +++ b/src/applications/config/check/PhorgeCodeWarningSetupCheck.php @@ -0,0 +1,81 @@ +getWarnings(); + if (!$warnings) { + return; + } + + $link = phutil_tag( + 'a', + array('href' => 'https://we.phorge.it/w/docs/report-warnings/'), + pht('%s\'s home page', PlatformSymbols::getPlatformServerName())); + + $message = pht( + 'There is some deprecated code found in the %s code-base.'. + "\n\n". + "This isn't a problem yet, but it means that %s might stop working if ". + 'you upgrade PHP version.'. + "\n\n". + 'This page records a sample of the cases since last server restart. '. + "\n\n". + 'To solve this issue, either:'. + "\n\n". + '- Visit %s, file bug report with the information below, or'. + "\n". + '- Ignore this issue using the `Ignore` button below.'. + "\n\n", + PlatformSymbols::getPlatformServerName(), + PlatformSymbols::getPlatformServerName(), + $link); + $message = array($message); + + $message[] = pht('PHP version: %s', phpversion()); + $message[] = "\n\n"; + + $message[] = pht('Recorded items (sample):'); + $list = array(); + $warnings = array_reverse(isort($warnings, 'counter')); + foreach ($warnings as $key => $data) { + $summary = pht( + '%s, occurrences: %s', + $key, + $data['counter']); + + $trace = phutil_tag('tt', array(), + array($data['message'] , "\n", $data['trace'])); + + $list[] = phutil_tag( + 'li', + array(), + phutil_tag( + 'details', + array(), + array( + phutil_tag('summary', array(), $summary), + $trace, + ))); + } + $message[] = phutil_tag('ul', array(), $list); + + + $this->newIssue('deprecations') + ->setName(pht('Deprecated Code')) + ->setMessage($message) + ->setSummary(pht('There is some deprecated code found in the code-base.')) + ->addLink( + 'https://we.phorge.it/w/docs/report-warnings/', + 'More Details on the website'); + } + +} diff --git a/src/applications/system/application/PhabricatorSystemApplication.php b/src/applications/system/application/PhabricatorSystemApplication.php index 6184c0de24..f3abc54d14 100644 --- a/src/applications/system/application/PhabricatorSystemApplication.php +++ b/src/applications/system/application/PhabricatorSystemApplication.php @@ -17,6 +17,7 @@ final class PhabricatorSystemApplication extends PhabricatorApplication { public function getEventListeners() { return array( new PhabricatorSystemDebugUIEventListener(), + new PhorgeSystemDeprecationWarningListener(), ); } diff --git a/src/applications/system/events/PhorgeSystemDeprecationWarningListener.php b/src/applications/system/events/PhorgeSystemDeprecationWarningListener.php new file mode 100644 index 0000000000..147e84a584 --- /dev/null +++ b/src/applications/system/events/PhorgeSystemDeprecationWarningListener.php @@ -0,0 +1,58 @@ +getKey(self::CACHE_KEY); + + if (!$cache_entry) { + $cache_entry = array(); + } + + $trace_entry = idx($cache_entry, $trace_key); + + if ($trace_entry) { + $trace_entry['counter']++; + } else { + $trace_entry = array( + 'counter' => 1, + 'message' => $value, + 'trace' => PhutilErrorHandler::formatStacktrace($metadata['trace']), + ); + } + $cache_entry[$trace_key] = $trace_entry; + + $cache->setKey(self::CACHE_KEY , $cache_entry); + } + + public function getWarnings() { + $cache = PhabricatorCaches::getRuntimeCache(); + return $cache->getKey(self::CACHE_KEY); + } + +}