From 0de00003c69dbb1671f80cecee9779cd0870ed2e Mon Sep 17 00:00:00 2001 From: Art4 Date: Mon, 13 Jan 2025 22:38:07 +0000 Subject: [PATCH 01/19] add Backward Compatibility Promise --- doc/Developers-Intro.md | 73 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) diff --git a/doc/Developers-Intro.md b/doc/Developers-Intro.md index c500b27741..e37313c73f 100644 --- a/doc/Developers-Intro.md +++ b/doc/Developers-Intro.md @@ -156,3 +156,76 @@ If you are interested in improving those clients, please contact the developers * iOS: *currently no client* * SailfishOS: **Friendiy** [src](https://kirgroup.com/projects/fabrixxm/harbour-friendly) - developed by [Fabio](https://kirgroup.com/profile/fabrixxm/profile) * Windows: **Friendica Mobile** for Windows versions [before 8.1](http://windowsphone.com/s?appid=e3257730-c9cf-4935-9620-5261e3505c67) and [Windows 10](https://www.microsoft.com/store/apps/9nblggh0fhmn) - developed by [Gerhard Seeber](http://mozartweg.dyndns.org/friendica/profile/gerhard/profile) + +## Backward compatability + +### Backward Compatibility Promise + +Friendica can be extended by addons. These addons relies on many internal classes and conventions. As developers our work on Friendica should not break things in the addons without giving the addon maintainers a chance to fix their addons. Our goal is to build trust for the addon maintainers but also allow Friendica developers to move on. This is called the Backward Compatibility Promise. + +We promise BC inside every major release. If one release breaks BC, this should considered as a bug and will be fix in a bugfix release. + +Inspired by the [Symonfy BC promise](https://symfony.com/doc/current/contributing/code/bc.html) we promise BC for every class, interface, trait, enum, function, constant, etc., but with the exception of: + +- Classes, interfaces, traits, enums, functions, methods, properties and constants marked as `@internal` or `@private` +- Extending or modifying a `final` class or method in any way +- Calling `private` methods (via Reflection) +- Accessing `private` propertyies (via Reflection) +- Accessing `private` methods (via Reflection) +- Accessing `private` constants (via Reflection) +- New properties on overrided `protected` methods +- Possible name collisions with new methods in an extended class (addon developers should prefix their custom methods in the extending classes in an appropriate way) +- Dropping support for every PHP version that has reached end of life + +Breaking changes will be happen only in a new release but MUST be hard deprecated first. + +### Deprecation and removing features + +As the development goes by Friendica needs to get rid of old code and concepts. This will be done in 3 steps to give addon maintainer a chance to adjust their addons. + +**1. Label deprecation** + +If we as the Friendica maintainers decide to remove some functions, classes, interface, etc. we start this by adding a `@deprecated` PHPDoc note on the code. For instance the class `Friendica\Core\Logger` should be removed, so we add the following note with a possible replacement. + +```php +/** + * Logger functions + * + * @deprecated 2025.02 Use constructor injection or `DI::logger()` instead + */ +class Logger {/* ... */} +``` + +This way addons developers might be notified by their IDE or other tools that the usage of the class is deprecated. In Friendica we can now start to replace all occurences and usage of this class with the alternative. + +The deprecation albel COULD be remain over multiple releases. As long as the deprecated code is used inside Friendica or the offical addon repository, it SHOULD NOT be hard deprecated. + +**2. Hard deprecation** + +If the deprecated code is no longer used inside Friendica or the offical addons it MUST be hard deprecated. The code MUST NOT be deleted. It MUST be stay for at least to the next major release. + +Hard deprecation code means that the code triggers an `E_USER_DEPRECATION` error if it is called. For instance with the deprecated class `Friendica\Core\Logger` the call of every method should be trigger an error: + +```php +/** + * Logger functions + * + * @deprecated 2025.02 Use constructor injection or `DI::logger()` instead + */ +class Logger { + public static function info(string $message, array $context = []) + { + trigger_error('Class `' . __CLASS__ . '` is deprecated since 2025.02 and will be removed in the next major release, use constructor injection or `DI::logger()` instead.', E_USER_DEPRECATED); + + self::getInstance()->info($message, $context); + } + + /* ... */ +} +``` + +This way the maintainer or users of addons will be notified that the addon will stop working in the next release. The addon maintainer now has the time until the next release to fix the deprecations. + +**3. Code Removing** + +Once a major release is published we as the Friendica maintainers can remove all code that is hard deprecated. From 34e6d29d1fd1a501bc15873434bf7445feccf1dd Mon Sep 17 00:00:00 2001 From: Artur Weigandt Date: Mon, 13 Jan 2025 23:56:27 +0100 Subject: [PATCH 02/19] Apply suggestions from code review --- doc/Developers-Intro.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/doc/Developers-Intro.md b/doc/Developers-Intro.md index e37313c73f..d44a2c6224 100644 --- a/doc/Developers-Intro.md +++ b/doc/Developers-Intro.md @@ -170,7 +170,7 @@ Inspired by the [Symonfy BC promise](https://symfony.com/doc/current/contributin - Classes, interfaces, traits, enums, functions, methods, properties and constants marked as `@internal` or `@private` - Extending or modifying a `final` class or method in any way - Calling `private` methods (via Reflection) -- Accessing `private` propertyies (via Reflection) +- Accessing `private` properties (via Reflection) - Accessing `private` methods (via Reflection) - Accessing `private` constants (via Reflection) - New properties on overrided `protected` methods @@ -196,13 +196,13 @@ If we as the Friendica maintainers decide to remove some functions, classes, int class Logger {/* ... */} ``` -This way addons developers might be notified by their IDE or other tools that the usage of the class is deprecated. In Friendica we can now start to replace all occurences and usage of this class with the alternative. +This way addon developers might be notified by their IDE or other tools that the usage of the class is deprecated. In Friendica we can now start to replace all occurrences and usage of this class with the alternative. -The deprecation albel COULD be remain over multiple releases. As long as the deprecated code is used inside Friendica or the offical addon repository, it SHOULD NOT be hard deprecated. +The deprecation label COULD be remain over multiple releases. As long as the deprecated code is used inside Friendica or the official addon repository, it SHOULD NOT be hard deprecated. **2. Hard deprecation** -If the deprecated code is no longer used inside Friendica or the offical addons it MUST be hard deprecated. The code MUST NOT be deleted. It MUST be stay for at least to the next major release. +If the deprecated code is no longer used inside Friendica or the official addons it MUST be hard deprecated. The code MUST NOT be deleted. It MUST be stay for at least to the next major release. Hard deprecation code means that the code triggers an `E_USER_DEPRECATION` error if it is called. For instance with the deprecated class `Friendica\Core\Logger` the call of every method should be trigger an error: From 3801382ffe7c73826b09f3fcb1588961c35a3431 Mon Sep 17 00:00:00 2001 From: Artur Weigandt Date: Tue, 14 Jan 2025 19:52:03 +0100 Subject: [PATCH 03/19] Update doc/Developers-Intro.md --- doc/Developers-Intro.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/Developers-Intro.md b/doc/Developers-Intro.md index d44a2c6224..e9236f6934 100644 --- a/doc/Developers-Intro.md +++ b/doc/Developers-Intro.md @@ -163,7 +163,7 @@ If you are interested in improving those clients, please contact the developers Friendica can be extended by addons. These addons relies on many internal classes and conventions. As developers our work on Friendica should not break things in the addons without giving the addon maintainers a chance to fix their addons. Our goal is to build trust for the addon maintainers but also allow Friendica developers to move on. This is called the Backward Compatibility Promise. -We promise BC inside every major release. If one release breaks BC, this should considered as a bug and will be fix in a bugfix release. +We promise BC for deprecated code for at least 6 month. After this time the deprecated code will be remove with the next release. If a release breaks BC without deprecation, this SHOULD considered as a bug and BC SHOULD be restored in a bugfix release. Inspired by the [Symonfy BC promise](https://symfony.com/doc/current/contributing/code/bc.html) we promise BC for every class, interface, trait, enum, function, constant, etc., but with the exception of: From 3dc467e208ceae967e569809adabc09ab0476d93 Mon Sep 17 00:00:00 2001 From: Artur Weigandt Date: Tue, 14 Jan 2025 20:29:20 +0100 Subject: [PATCH 04/19] Increase BC to 6 months --- doc/Developers-Intro.md | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/doc/Developers-Intro.md b/doc/Developers-Intro.md index e9236f6934..39462d20f7 100644 --- a/doc/Developers-Intro.md +++ b/doc/Developers-Intro.md @@ -157,14 +157,12 @@ If you are interested in improving those clients, please contact the developers * SailfishOS: **Friendiy** [src](https://kirgroup.com/projects/fabrixxm/harbour-friendly) - developed by [Fabio](https://kirgroup.com/profile/fabrixxm/profile) * Windows: **Friendica Mobile** for Windows versions [before 8.1](http://windowsphone.com/s?appid=e3257730-c9cf-4935-9620-5261e3505c67) and [Windows 10](https://www.microsoft.com/store/apps/9nblggh0fhmn) - developed by [Gerhard Seeber](http://mozartweg.dyndns.org/friendica/profile/gerhard/profile) -## Backward compatability +## Backward compatibility ### Backward Compatibility Promise Friendica can be extended by addons. These addons relies on many internal classes and conventions. As developers our work on Friendica should not break things in the addons without giving the addon maintainers a chance to fix their addons. Our goal is to build trust for the addon maintainers but also allow Friendica developers to move on. This is called the Backward Compatibility Promise. -We promise BC for deprecated code for at least 6 month. After this time the deprecated code will be remove with the next release. If a release breaks BC without deprecation, this SHOULD considered as a bug and BC SHOULD be restored in a bugfix release. - Inspired by the [Symonfy BC promise](https://symfony.com/doc/current/contributing/code/bc.html) we promise BC for every class, interface, trait, enum, function, constant, etc., but with the exception of: - Classes, interfaces, traits, enums, functions, methods, properties and constants marked as `@internal` or `@private` @@ -173,12 +171,10 @@ Inspired by the [Symonfy BC promise](https://symfony.com/doc/current/contributin - Accessing `private` properties (via Reflection) - Accessing `private` methods (via Reflection) - Accessing `private` constants (via Reflection) -- New properties on overrided `protected` methods +- New properties on overridden `protected` methods - Possible name collisions with new methods in an extended class (addon developers should prefix their custom methods in the extending classes in an appropriate way) - Dropping support for every PHP version that has reached end of life -Breaking changes will be happen only in a new release but MUST be hard deprecated first. - ### Deprecation and removing features As the development goes by Friendica needs to get rid of old code and concepts. This will be done in 3 steps to give addon maintainer a chance to adjust their addons. @@ -196,13 +192,13 @@ If we as the Friendica maintainers decide to remove some functions, classes, int class Logger {/* ... */} ``` -This way addon developers might be notified by their IDE or other tools that the usage of the class is deprecated. In Friendica we can now start to replace all occurrences and usage of this class with the alternative. +This way addon developers might be notified early by their IDE or other tools that the usage of the class is deprecated. In Friendica we can now start to replace all occurrences and usage of this class with the alternative. -The deprecation label COULD be remain over multiple releases. As long as the deprecated code is used inside Friendica or the official addon repository, it SHOULD NOT be hard deprecated. +The deprecation label COULD be remain over multiple releases. As long as the `@deprecated` labeled code is used inside Friendica or the official addon repository, it SHOULD NOT be hard deprecated. **2. Hard deprecation** -If the deprecated code is no longer used inside Friendica or the official addons it MUST be hard deprecated. The code MUST NOT be deleted. It MUST be stay for at least to the next major release. +If the deprecated code is no longer used inside Friendica or the official addons it MUST be hard deprecated. The code MUST NOT be deleted. Starting from the next release, it MUST be stay for at least 6 months. Hard deprecated code COULD remain longer than 6 months, depending on when a release appears. Addon developer MUST NOT consider that they have more than 6 months to adjust their code. Hard deprecation code means that the code triggers an `E_USER_DEPRECATION` error if it is called. For instance with the deprecated class `Friendica\Core\Logger` the call of every method should be trigger an error: @@ -215,17 +211,23 @@ Hard deprecation code means that the code triggers an `E_USER_DEPRECATION` error class Logger { public static function info(string $message, array $context = []) { - trigger_error('Class `' . __CLASS__ . '` is deprecated since 2025.02 and will be removed in the next major release, use constructor injection or `DI::logger()` instead.', E_USER_DEPRECATED); + trigger_error('Class `' . __CLASS__ . '` is deprecated since 2025.05 and will be removed after 6 months, use constructor injection or `DI::logger()` instead.', E_USER_DEPRECATED); self::getInstance()->info($message, $context); } - /* ... */ + /* ... */ } ``` -This way the maintainer or users of addons will be notified that the addon will stop working in the next release. The addon maintainer now has the time until the next release to fix the deprecations. +This way the maintainer or users of addons will be notified that the addon will stop working in one of the next releases. The addon maintainer now has at least 6 months to fix the deprecations. + +Please note that the deprecation message contains the release that will be released next. In the example the code was hard deprecated in `2025.05` and COULD be removed earliest with the `2025.11` release. **3. Code Removing** -Once a major release is published we as the Friendica maintainers can remove all code that is hard deprecated. +We promise BC for deprecated code for at least 6 month, starting from the release the deprecation was announced. After this time the deprecated code COULD be remove within the next release. + +Breaking changes MUST be happen only in a new release but MUST be hard deprecated first. The BC promise refers only to releases, respective the `stable` branch. Deprecated code on other branches like `develop` or RC branches could be removed earlier. This is not a BC break as long as the release is published 6 months after the deprecation. + +If a release breaks BC without deprecation or earlier than 6 months, this SHOULD considered as a bug and BC SHOULD be restored in a bugfix release. From 11593bb88732f0dc97acc89c0e1d1bba6aa172f4 Mon Sep 17 00:00:00 2001 From: Artur Weigandt Date: Thu, 16 Jan 2025 16:07:32 +0100 Subject: [PATCH 05/19] Adjust fromat --- doc/Developers-Intro.md | 41 ++++++++++++++++++++++++++++++----------- 1 file changed, 30 insertions(+), 11 deletions(-) diff --git a/doc/Developers-Intro.md b/doc/Developers-Intro.md index 39462d20f7..f07b711648 100644 --- a/doc/Developers-Intro.md +++ b/doc/Developers-Intro.md @@ -161,7 +161,11 @@ If you are interested in improving those clients, please contact the developers ### Backward Compatibility Promise -Friendica can be extended by addons. These addons relies on many internal classes and conventions. As developers our work on Friendica should not break things in the addons without giving the addon maintainers a chance to fix their addons. Our goal is to build trust for the addon maintainers but also allow Friendica developers to move on. This is called the Backward Compatibility Promise. +Friendica can be extended by addons. +These addons relies on many classes and conventions from Friendica. +As developers our work on Friendica should not break things in the addons without giving the addon maintainers a chance to fix their addons. +Our goal is to build trust for the addon maintainers but also allow Friendica developers to move on. +This is called the Backward Compatibility Promise. Inspired by the [Symonfy BC promise](https://symfony.com/doc/current/contributing/code/bc.html) we promise BC for every class, interface, trait, enum, function, constant, etc., but with the exception of: @@ -177,11 +181,13 @@ Inspired by the [Symonfy BC promise](https://symfony.com/doc/current/contributin ### Deprecation and removing features -As the development goes by Friendica needs to get rid of old code and concepts. This will be done in 3 steps to give addon maintainer a chance to adjust their addons. +As the development goes by Friendica needs to get rid of old code and concepts. +This will be done in 3 steps to give addon maintainers a chance to adjust their addons. **1. Label deprecation** -If we as the Friendica maintainers decide to remove some functions, classes, interface, etc. we start this by adding a `@deprecated` PHPDoc note on the code. For instance the class `Friendica\Core\Logger` should be removed, so we add the following note with a possible replacement. +If we as the Friendica maintainers decide to remove some functions, classes, interface, etc. we start this by adding a `@deprecated` PHPDoc note on the code. +For instance the class `Friendica\Core\Logger` should be removed, so we add the following note with a possible replacement: ```php /** @@ -192,15 +198,22 @@ If we as the Friendica maintainers decide to remove some functions, classes, int class Logger {/* ... */} ``` -This way addon developers might be notified early by their IDE or other tools that the usage of the class is deprecated. In Friendica we can now start to replace all occurrences and usage of this class with the alternative. +This way addon developers might be notified early by their IDE or other tools that the usage of the class is deprecated. +In Friendica we can now start to replace all occurrences and usage of this class with the alternative. -The deprecation label COULD be remain over multiple releases. As long as the `@deprecated` labeled code is used inside Friendica or the official addon repository, it SHOULD NOT be hard deprecated. +The deprecation label COULD be remain over multiple releases. +As long as the code that is labeled with `@deprecated` is used inside Friendica or the official addon repository, it SHOULD NOT be hard deprecated. **2. Hard deprecation** -If the deprecated code is no longer used inside Friendica or the official addons it MUST be hard deprecated. The code MUST NOT be deleted. Starting from the next release, it MUST be stay for at least 6 months. Hard deprecated code COULD remain longer than 6 months, depending on when a release appears. Addon developer MUST NOT consider that they have more than 6 months to adjust their code. +If the deprecated code is no longer used inside Friendica or the official addons it MUST be hard deprecated. +The code MUST NOT be deleted. +Starting from the next release, it MUST be stay for at least 6 months. +Hard deprecated code COULD remain longer than 6 months, depending on when a release appears. +Addon developer MUST NOT consider that they have more than 6 months to adjust their code. -Hard deprecation code means that the code triggers an `E_USER_DEPRECATION` error if it is called. For instance with the deprecated class `Friendica\Core\Logger` the call of every method should be trigger an error: +Hard deprecation code means that the code triggers an `E_USER_DEPRECATION` error if it is called. +For instance with the deprecated class `Friendica\Core\Logger` the call of every method should be trigger an error: ```php /** @@ -220,14 +233,20 @@ class Logger { } ``` -This way the maintainer or users of addons will be notified that the addon will stop working in one of the next releases. The addon maintainer now has at least 6 months to fix the deprecations. +This way the maintainer or users of addons will be notified that the addon will stop working in one of the next releases. +The addon maintainer now has at least 6 months to fix the deprecations. -Please note that the deprecation message contains the release that will be released next. In the example the code was hard deprecated in `2025.05` and COULD be removed earliest with the `2025.11` release. +Please note that the deprecation message contains the release that will be released next. +In the example the code was hard deprecated in `2025.05` and COULD be removed earliest with the `2025.11` release. **3. Code Removing** -We promise BC for deprecated code for at least 6 month, starting from the release the deprecation was announced. After this time the deprecated code COULD be remove within the next release. +We promise BC for deprecated code for at least 6 months, starting from the release the deprecation was announced. +After this time the deprecated code COULD be remove within the next release. -Breaking changes MUST be happen only in a new release but MUST be hard deprecated first. The BC promise refers only to releases, respective the `stable` branch. Deprecated code on other branches like `develop` or RC branches could be removed earlier. This is not a BC break as long as the release is published 6 months after the deprecation. +Breaking changes MUST be happen only in a new release but MUST be hard deprecated first. +The BC promise refers only to releases, respective the `stable` branch. +Deprecated code on other branches like `develop` or RC branches could be removed earlier. +This is not a BC break as long as the release is published 6 months after the deprecation. If a release breaks BC without deprecation or earlier than 6 months, this SHOULD considered as a bug and BC SHOULD be restored in a bugfix release. From b9f5a4f7453f6c5be2a0989023991a75b8c0a907 Mon Sep 17 00:00:00 2001 From: Art4 Date: Wed, 22 Jan 2025 10:53:34 +0000 Subject: [PATCH 06/19] Rename back App::load() --- src/App.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/App.php b/src/App.php index 73f2913b1a..776b5ea909 100644 --- a/src/App.php +++ b/src/App.php @@ -158,7 +158,7 @@ class App $this->session = $this->container->create(IHandleUserSessions::class); $this->appHelper = $this->container->create(AppHelper::class); - $this->loadSetupForFrontend( + $this->load( $request, $this->container->create(DbaDefinition::class), $this->container->create(ViewDefinition::class), @@ -272,7 +272,7 @@ class App /** * Load the whole app instance */ - private function loadSetupForFrontend(ServerRequestInterface $request, DbaDefinition $dbaDefinition, ViewDefinition $viewDefinition) + private function load(ServerRequestInterface $request, DbaDefinition $dbaDefinition, ViewDefinition $viewDefinition) { if ($this->config->get('system', 'ini_max_execution_time') !== false) { set_time_limit((int)$this->config->get('system', 'ini_max_execution_time')); From bf28afb65100cc2ae3bad5929d113639dc3101a0 Mon Sep 17 00:00:00 2001 From: Art4 Date: Wed, 22 Jan 2025 11:56:23 +0000 Subject: [PATCH 07/19] Remove dependency for ServerRequestInterface in App::load() --- src/App.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/App.php b/src/App.php index 776b5ea909..5ee8562dbf 100644 --- a/src/App.php +++ b/src/App.php @@ -159,7 +159,7 @@ class App $this->appHelper = $this->container->create(AppHelper::class); $this->load( - $request, + $request->getServerParams(), $this->container->create(DbaDefinition::class), $this->container->create(ViewDefinition::class), ); @@ -272,7 +272,7 @@ class App /** * Load the whole app instance */ - private function load(ServerRequestInterface $request, DbaDefinition $dbaDefinition, ViewDefinition $viewDefinition) + private function load(array $serverParams, DbaDefinition $dbaDefinition, ViewDefinition $viewDefinition) { if ($this->config->get('system', 'ini_max_execution_time') !== false) { set_time_limit((int)$this->config->get('system', 'ini_max_execution_time')); @@ -294,7 +294,7 @@ class App if ($this->mode->has(Mode::DBAVAILABLE)) { Core\Hook::loadHooks(); - $loader = (new Config())->createConfigFileManager($this->appHelper->getBasePath(), $request->getServerParams()); + $loader = (new Config())->createConfigFileManager($this->appHelper->getBasePath(), $serverParams); Core\Hook::callAll('load_config', $loader); // Hooks are now working, reload the whole definitions with hook enabled From 064b70f4c0f1318d5993f2fe830fa359bedacf53 Mon Sep 17 00:00:00 2001 From: Art4 Date: Wed, 22 Jan 2025 11:59:24 +0000 Subject: [PATCH 08/19] Move Mode::setExecutor() call inside App::runFrontend() --- src/App.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/App.php b/src/App.php index 5ee8562dbf..6546d56778 100644 --- a/src/App.php +++ b/src/App.php @@ -166,8 +166,6 @@ class App $this->registerTemplateEngine(); - $this->mode->setExecutor(Mode::INDEX); - $this->runFrontend( $this->container->create(IManagePersonalConfigValues::class), $this->container->create(Page::class), @@ -348,6 +346,8 @@ class App float $start_time, ServerRequestInterface $request ) { + $this->mode->setExecutor(Mode::INDEX); + $httpInput = new HTTPInputData($request->getServerParams()); $serverVars = $request->getServerParams(); $queryVars = $request->getQueryParams(); From 76aec2d5750f10eeb2603972ac0eb9bbc62a28c8 Mon Sep 17 00:00:00 2001 From: Art4 Date: Wed, 22 Jan 2025 12:06:53 +0000 Subject: [PATCH 09/19] Inject Mode into App::load() via parameter --- src/App.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/App.php b/src/App.php index 6546d56778..c823cfd5b3 100644 --- a/src/App.php +++ b/src/App.php @@ -162,6 +162,7 @@ class App $request->getServerParams(), $this->container->create(DbaDefinition::class), $this->container->create(ViewDefinition::class), + $this->mode, ); $this->registerTemplateEngine(); @@ -270,7 +271,7 @@ class App /** * Load the whole app instance */ - private function load(array $serverParams, DbaDefinition $dbaDefinition, ViewDefinition $viewDefinition) + private function load(array $serverParams, DbaDefinition $dbaDefinition, ViewDefinition $viewDefinition, Mode $mode) { if ($this->config->get('system', 'ini_max_execution_time') !== false) { set_time_limit((int)$this->config->get('system', 'ini_max_execution_time')); @@ -290,7 +291,7 @@ class App $this->profiler->reset(); - if ($this->mode->has(Mode::DBAVAILABLE)) { + if ($mode->has(Mode::DBAVAILABLE)) { Core\Hook::loadHooks(); $loader = (new Config())->createConfigFileManager($this->appHelper->getBasePath(), $serverParams); Core\Hook::callAll('load_config', $loader); From 52c6f93c9adc497decc7abf75b17ecf345b279da Mon Sep 17 00:00:00 2001 From: Art4 Date: Wed, 22 Jan 2025 12:11:06 +0000 Subject: [PATCH 10/19] Inject Mode into App::runFrontend() via parameter --- src/App.php | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/src/App.php b/src/App.php index c823cfd5b3..6cda9d989b 100644 --- a/src/App.php +++ b/src/App.php @@ -168,6 +168,7 @@ class App $this->registerTemplateEngine(); $this->runFrontend( + $this->mode, $this->container->create(IManagePersonalConfigValues::class), $this->container->create(Page::class), $this->container->create(Nav::class), @@ -340,6 +341,7 @@ class App * @throws \ImagickException */ private function runFrontend( + Mode $mode, IManagePersonalConfigValues $pconfig, Page $page, Nav $nav, @@ -347,7 +349,7 @@ class App float $start_time, ServerRequestInterface $request ) { - $this->mode->setExecutor(Mode::INDEX); + $mode->setExecutor(Mode::INDEX); $httpInput = new HTTPInputData($request->getServerParams()); $serverVars = $request->getServerParams(); @@ -366,11 +368,11 @@ class App try { // Missing DB connection: ERROR - if ($this->mode->has(Mode::LOCALCONFIGPRESENT) && !$this->mode->has(Mode::DBAVAILABLE)) { + if ($mode->has(Mode::LOCALCONFIGPRESENT) && !$mode->has(Mode::DBAVAILABLE)) { throw new HTTPException\InternalServerErrorException($this->l10n->t('Apologies but the website is unavailable at the moment.')); } - if (!$this->mode->isInstall()) { + if (!$mode->isInstall()) { // Force SSL redirection if ($this->config->get('system', 'force_ssl') && (empty($serverVars['HTTPS']) || $serverVars['HTTPS'] === 'off') && @@ -384,7 +386,7 @@ class App DID::routeRequest($this->args->getCommand(), $serverVars); - if ($this->mode->isNormal() && !$this->mode->isBackend()) { + if ($mode->isNormal() && !$mode->isBackend()) { $requester = HTTPSignature::getSigner('', $serverVars); if (!empty($requester)) { OpenWebAuth::addVisitorCookieForHandle($requester); @@ -392,7 +394,7 @@ class App } // ZRL - if (!empty($queryVars['zrl']) && $this->mode->isNormal() && !$this->mode->isBackend() && !$this->session->getLocalUserId()) { + if (!empty($queryVars['zrl']) && $mode->isNormal() && !$mode->isBackend() && !$this->session->getLocalUserId()) { // Only continue when the given profile link seems valid. // Valid profile links contain a path with "/profile/" and no query parameters if ((parse_url($queryVars['zrl'], PHP_URL_QUERY) == '') && @@ -407,12 +409,12 @@ class App } } - if (!empty($queryVars['owt']) && $this->mode->isNormal()) { + if (!empty($queryVars['owt']) && $mode->isNormal()) { $token = $queryVars['owt']; OpenWebAuth::init($token); } - if (!$this->mode->isBackend()) { + if (!$mode->isBackend()) { $this->auth->withSession(); } @@ -428,7 +430,7 @@ class App // in install mode, any url loads install module // but we need "view" module for stylesheet - if ($this->mode->isInstall() && $moduleName !== 'install') { + if ($mode->isInstall() && $moduleName !== 'install') { $this->baseURL->redirect('install'); } else { Core\Update::check($this->appHelper->getBasePath(), false); @@ -478,7 +480,7 @@ class App $page['page_title'] = $moduleName; // The "view" module is required to show the theme CSS - if (!$this->mode->isInstall() && !$this->mode->has(Mode::MAINTENANCEDISABLED) && $moduleName !== 'view') { + if (!$mode->isInstall() && !$mode->has(Mode::MAINTENANCEDISABLED) && $moduleName !== 'view') { $module = $this->createModuleInstance(Maintenance::class); } else { // determine the module class and save it to the module instance @@ -500,7 +502,7 @@ class App // Wrapping HTML responses in the theme template if ($response->getHeaderLine(ICanCreateResponses::X_HEADER) === ICanCreateResponses::TYPE_HTML) { - $response = $page->run($this->appHelper, $this->session, $this->baseURL, $this->args, $this->mode, $response, $this->l10n, $this->profiler, $this->config, $pconfig, $nav, $this->session->getLocalUserId()); + $response = $page->run($this->appHelper, $this->session, $this->baseURL, $this->args, $mode, $response, $this->l10n, $this->profiler, $this->config, $pconfig, $nav, $this->session->getLocalUserId()); } $this->logger->debug('Request processed sucessfully', ['response' => $response->getStatusCode(), 'address' => $serverVars['REMOTE_ADDR'] ?? '', 'request' => $requeststring, 'referer' => $serverVars['HTTP_REFERER'] ?? '', 'user-agent' => $serverVars['HTTP_USER_AGENT'] ?? '', 'duration' => number_format(microtime(true) - $request_start, 3)]); From fdb14f23f26dc935bb8108c030796b9d9c52f822 Mon Sep 17 00:00:00 2001 From: Art4 Date: Wed, 22 Jan 2025 12:13:57 +0000 Subject: [PATCH 11/19] Inject config into App::load() via parameter --- src/App.php | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/App.php b/src/App.php index 6cda9d989b..af8c391426 100644 --- a/src/App.php +++ b/src/App.php @@ -163,6 +163,7 @@ class App $this->container->create(DbaDefinition::class), $this->container->create(ViewDefinition::class), $this->mode, + $this->config, ); $this->registerTemplateEngine(); @@ -272,14 +273,19 @@ class App /** * Load the whole app instance */ - private function load(array $serverParams, DbaDefinition $dbaDefinition, ViewDefinition $viewDefinition, Mode $mode) - { - if ($this->config->get('system', 'ini_max_execution_time') !== false) { - set_time_limit((int)$this->config->get('system', 'ini_max_execution_time')); + private function load( + array $serverParams, + DbaDefinition $dbaDefinition, + ViewDefinition $viewDefinition, + Mode $mode, + IManageConfigValues $config + ): void { + if ($config->get('system', 'ini_max_execution_time') !== false) { + set_time_limit((int) $config->get('system', 'ini_max_execution_time')); } - if ($this->config->get('system', 'ini_pcre_backtrack_limit') !== false) { - ini_set('pcre.backtrack_limit', (int)$this->config->get('system', 'ini_pcre_backtrack_limit')); + if ($config->get('system', 'ini_pcre_backtrack_limit') !== false) { + ini_set('pcre.backtrack_limit', (int) $config->get('system', 'ini_pcre_backtrack_limit')); } // Normally this constant is defined - but not if "pcntl" isn't installed From 6c0a2eaefc385f2776224f73e07238c10aa81c33 Mon Sep 17 00:00:00 2001 From: Art4 Date: Wed, 22 Jan 2025 12:36:14 +0000 Subject: [PATCH 12/19] Inject config into App::loadDefaultTimezone() via parameter --- src/App.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/App.php b/src/App.php index af8c391426..41ae4fd1b7 100644 --- a/src/App.php +++ b/src/App.php @@ -308,7 +308,7 @@ class App $viewDefinition->load(true); } - $this->loadDefaultTimezone(); + $this->loadDefaultTimezone($config); } /** @@ -318,10 +318,10 @@ class App * * @global string $default_timezone */ - private function loadDefaultTimezone() + private function loadDefaultTimezone(IManageConfigValues $config) { - if ($this->config->get('system', 'default_timezone')) { - $timezone = $this->config->get('system', 'default_timezone', 'UTC'); + if ($config->get('system', 'default_timezone')) { + $timezone = $config->get('system', 'default_timezone', 'UTC'); } else { global $default_timezone; $timezone = $default_timezone ?? '' ?: 'UTC'; From e57424ec35aa8df1ffdf2faf9713c1f699f2546d Mon Sep 17 00:00:00 2001 From: Art4 Date: Wed, 22 Jan 2025 12:46:24 +0000 Subject: [PATCH 13/19] Inject profiler into App::load() via parameter --- src/App.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/App.php b/src/App.php index 41ae4fd1b7..af1147e091 100644 --- a/src/App.php +++ b/src/App.php @@ -164,6 +164,7 @@ class App $this->container->create(ViewDefinition::class), $this->mode, $this->config, + $this->profiler, ); $this->registerTemplateEngine(); @@ -278,7 +279,8 @@ class App DbaDefinition $dbaDefinition, ViewDefinition $viewDefinition, Mode $mode, - IManageConfigValues $config + IManageConfigValues $config, + Profiler $profiler ): void { if ($config->get('system', 'ini_max_execution_time') !== false) { set_time_limit((int) $config->get('system', 'ini_max_execution_time')); @@ -296,7 +298,7 @@ class App // Ensure that all "strtotime" operations do run timezone independent date_default_timezone_set('UTC'); - $this->profiler->reset(); + $profiler->reset(); if ($mode->has(Mode::DBAVAILABLE)) { Core\Hook::loadHooks(); From 7cc37ff2cb972da993134c173e99b817a3778982 Mon Sep 17 00:00:00 2001 From: Art4 Date: Wed, 22 Jan 2025 13:17:53 +0000 Subject: [PATCH 14/19] Inject AppHelper into App::load() via parameter --- src/App.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/App.php b/src/App.php index af1147e091..6ebac26d49 100644 --- a/src/App.php +++ b/src/App.php @@ -165,6 +165,7 @@ class App $this->mode, $this->config, $this->profiler, + $this->appHelper, ); $this->registerTemplateEngine(); @@ -280,7 +281,8 @@ class App ViewDefinition $viewDefinition, Mode $mode, IManageConfigValues $config, - Profiler $profiler + Profiler $profiler, + AppHelper $appHelper ): void { if ($config->get('system', 'ini_max_execution_time') !== false) { set_time_limit((int) $config->get('system', 'ini_max_execution_time')); @@ -302,7 +304,7 @@ class App if ($mode->has(Mode::DBAVAILABLE)) { Core\Hook::loadHooks(); - $loader = (new Config())->createConfigFileManager($this->appHelper->getBasePath(), $serverParams); + $loader = (new Config())->createConfigFileManager($appHelper->getBasePath(), $serverParams); Core\Hook::callAll('load_config', $loader); // Hooks are now working, reload the whole definitions with hook enabled From 15446f35a5943d243521a53e76d90c40f6d709ff Mon Sep 17 00:00:00 2001 From: Art4 Date: Wed, 22 Jan 2025 13:19:17 +0000 Subject: [PATCH 15/19] Inject AppHelper into App::loadDefaultTimezone() via parameter --- src/App.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/App.php b/src/App.php index 6ebac26d49..8af9ec9272 100644 --- a/src/App.php +++ b/src/App.php @@ -312,7 +312,7 @@ class App $viewDefinition->load(true); } - $this->loadDefaultTimezone($config); + $this->loadDefaultTimezone($config, $appHelper); } /** @@ -322,7 +322,7 @@ class App * * @global string $default_timezone */ - private function loadDefaultTimezone(IManageConfigValues $config) + private function loadDefaultTimezone(IManageConfigValues $config, AppHelper $appHelper) { if ($config->get('system', 'default_timezone')) { $timezone = $config->get('system', 'default_timezone', 'UTC'); @@ -331,7 +331,7 @@ class App $timezone = $default_timezone ?? '' ?: 'UTC'; } - $this->appHelper->setTimeZone($timezone); + $appHelper->setTimeZone($timezone); } /** From c9bcc45d7cb578eaddcdf38afa55cd94669bd702 Mon Sep 17 00:00:00 2001 From: Art4 Date: Wed, 22 Jan 2025 13:47:58 +0000 Subject: [PATCH 16/19] Provide $_SERVER to App::processConsole() --- bin/console.php | 2 +- bin/daemon.php | 4 +++- bin/jetstream.php | 4 +++- bin/worker.php | 4 +++- src/App.php | 5 ++++- 5 files changed, 14 insertions(+), 5 deletions(-) diff --git a/bin/console.php b/bin/console.php index ad612f4363..a20f3f7e02 100755 --- a/bin/console.php +++ b/bin/console.php @@ -19,4 +19,4 @@ $container = \Friendica\Core\DiceContainer::fromBasePath(dirname(__DIR__)); $app = \Friendica\App::fromContainer($container); -$app->processConsole($_SERVER['argv'] ?? []); +$app->processConsole($_SERVER); diff --git a/bin/daemon.php b/bin/daemon.php index 546f207e08..25f902eacd 100755 --- a/bin/daemon.php +++ b/bin/daemon.php @@ -24,11 +24,13 @@ chdir(dirname(__DIR__)); require dirname(__DIR__) . '/vendor/autoload.php'; +// BC: Add console command as second argument $argv = $_SERVER['argv'] ?? []; array_splice($argv, 1, 0, "daemon"); +$_SERVER['argv'] = $argv; $container = \Friendica\Core\DiceContainer::fromBasePath(dirname(__DIR__)); $app = \Friendica\App::fromContainer($container); -$app->processConsole($argv); +$app->processConsole($_SERVER); diff --git a/bin/jetstream.php b/bin/jetstream.php index 156f961856..b96dfa0e51 100755 --- a/bin/jetstream.php +++ b/bin/jetstream.php @@ -19,11 +19,13 @@ chdir(dirname(__DIR__)); require dirname(__DIR__) . '/vendor/autoload.php'; +// BC: Add console command as second argument $argv = $_SERVER['argv'] ?? []; array_splice($argv, 1, 0, "jetstream"); +$_SERVER['argv'] = $argv; $container = \Friendica\Core\DiceContainer::fromBasePath(dirname(__DIR__)); $app = \Friendica\App::fromContainer($container); -$app->processConsole($argv); +$app->processConsole($_SERVER); diff --git a/bin/worker.php b/bin/worker.php index a79d8836a7..b72a8e2514 100755 --- a/bin/worker.php +++ b/bin/worker.php @@ -21,11 +21,13 @@ chdir(dirname(__DIR__)); require dirname(__DIR__) . '/vendor/autoload.php'; +// BC: Add console command as second argument $argv = $_SERVER['argv'] ?? []; array_splice($argv, 1, 0, "worker"); +$_SERVER['argv'] = $argv; $container = \Friendica\Core\DiceContainer::fromBasePath(dirname(__DIR__)); $app = \Friendica\App::fromContainer($container); -$app->processConsole($argv); +$app->processConsole($_SERVER); diff --git a/src/App.php b/src/App.php index 8af9ec9272..6bdb20d45c 100644 --- a/src/App.php +++ b/src/App.php @@ -181,8 +181,11 @@ class App ); } - public function processConsole(array $argv): void + + public function processConsole(array $serverParams): void { + $argv = $serverParams['argv'] ?? []; + $this->setupContainerForAddons(); $this->setupLogChannel($this->determineLogChannel($argv)); From 5a40fdd7e1dc5fce26511afd7101ed17074c43be Mon Sep 17 00:00:00 2001 From: Art4 Date: Wed, 22 Jan 2025 13:53:30 +0000 Subject: [PATCH 17/19] Call App::load() on App::processConsole() and procesEjabberd() --- bin/auth_ejabberd.php | 2 +- src/App.php | 22 +++++++++++++++++++++- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/bin/auth_ejabberd.php b/bin/auth_ejabberd.php index bc976e61a4..595ccf204a 100755 --- a/bin/auth_ejabberd.php +++ b/bin/auth_ejabberd.php @@ -52,4 +52,4 @@ $container = \Friendica\Core\DiceContainer::fromBasePath(dirname(__DIR__)); $app = \Friendica\App::fromContainer($container); -$app->processEjabberd(); +$app->processEjabberd($_SERVER); diff --git a/src/App.php b/src/App.php index 6bdb20d45c..d622eacbb5 100644 --- a/src/App.php +++ b/src/App.php @@ -194,12 +194,22 @@ class App $this->registerErrorHandler(); + $this->load( + $serverParams, + $this->container->create(DbaDefinition::class), + $this->container->create(ViewDefinition::class), + $this->container->create(Mode::class), + $this->container->create(IManageConfigValues::class), + $this->container->create(Profiler::class), + $this->container->create(AppHelper::class), + ); + $this->registerTemplateEngine(); (\Friendica\Core\Console::create($this->container, $argv))->execute(); } - public function processEjabberd(): void + public function processEjabberd(array $serverParams): void { $this->setupContainerForAddons(); @@ -209,6 +219,16 @@ class App $this->registerErrorHandler(); + $this->load( + $serverParams, + $this->container->create(DbaDefinition::class), + $this->container->create(ViewDefinition::class), + $this->container->create(Mode::class), + $this->container->create(IManageConfigValues::class), + $this->container->create(Profiler::class), + $this->container->create(AppHelper::class), + ); + /** @var BasePath */ $basePath = $this->container->create(BasePath::class); From ed184ab52091ece1d77f2f61fb4d6e8b09640bce Mon Sep 17 00:00:00 2001 From: Art4 Date: Wed, 22 Jan 2025 13:58:50 +0000 Subject: [PATCH 18/19] Revert "Inject Mode into App::runFrontend() via parameter" This reverts commit 52c6f93c9adc497decc7abf75b17ecf345b279da. --- src/App.php | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/src/App.php b/src/App.php index d622eacbb5..564da764f9 100644 --- a/src/App.php +++ b/src/App.php @@ -171,7 +171,6 @@ class App $this->registerTemplateEngine(); $this->runFrontend( - $this->mode, $this->container->create(IManagePersonalConfigValues::class), $this->container->create(Page::class), $this->container->create(Nav::class), @@ -374,7 +373,6 @@ class App * @throws \ImagickException */ private function runFrontend( - Mode $mode, IManagePersonalConfigValues $pconfig, Page $page, Nav $nav, @@ -382,7 +380,7 @@ class App float $start_time, ServerRequestInterface $request ) { - $mode->setExecutor(Mode::INDEX); + $this->mode->setExecutor(Mode::INDEX); $httpInput = new HTTPInputData($request->getServerParams()); $serverVars = $request->getServerParams(); @@ -401,11 +399,11 @@ class App try { // Missing DB connection: ERROR - if ($mode->has(Mode::LOCALCONFIGPRESENT) && !$mode->has(Mode::DBAVAILABLE)) { + if ($this->mode->has(Mode::LOCALCONFIGPRESENT) && !$this->mode->has(Mode::DBAVAILABLE)) { throw new HTTPException\InternalServerErrorException($this->l10n->t('Apologies but the website is unavailable at the moment.')); } - if (!$mode->isInstall()) { + if (!$this->mode->isInstall()) { // Force SSL redirection if ($this->config->get('system', 'force_ssl') && (empty($serverVars['HTTPS']) || $serverVars['HTTPS'] === 'off') && @@ -419,7 +417,7 @@ class App DID::routeRequest($this->args->getCommand(), $serverVars); - if ($mode->isNormal() && !$mode->isBackend()) { + if ($this->mode->isNormal() && !$this->mode->isBackend()) { $requester = HTTPSignature::getSigner('', $serverVars); if (!empty($requester)) { OpenWebAuth::addVisitorCookieForHandle($requester); @@ -427,7 +425,7 @@ class App } // ZRL - if (!empty($queryVars['zrl']) && $mode->isNormal() && !$mode->isBackend() && !$this->session->getLocalUserId()) { + if (!empty($queryVars['zrl']) && $this->mode->isNormal() && !$this->mode->isBackend() && !$this->session->getLocalUserId()) { // Only continue when the given profile link seems valid. // Valid profile links contain a path with "/profile/" and no query parameters if ((parse_url($queryVars['zrl'], PHP_URL_QUERY) == '') && @@ -442,12 +440,12 @@ class App } } - if (!empty($queryVars['owt']) && $mode->isNormal()) { + if (!empty($queryVars['owt']) && $this->mode->isNormal()) { $token = $queryVars['owt']; OpenWebAuth::init($token); } - if (!$mode->isBackend()) { + if (!$this->mode->isBackend()) { $this->auth->withSession(); } @@ -463,7 +461,7 @@ class App // in install mode, any url loads install module // but we need "view" module for stylesheet - if ($mode->isInstall() && $moduleName !== 'install') { + if ($this->mode->isInstall() && $moduleName !== 'install') { $this->baseURL->redirect('install'); } else { Core\Update::check($this->appHelper->getBasePath(), false); @@ -513,7 +511,7 @@ class App $page['page_title'] = $moduleName; // The "view" module is required to show the theme CSS - if (!$mode->isInstall() && !$mode->has(Mode::MAINTENANCEDISABLED) && $moduleName !== 'view') { + if (!$this->mode->isInstall() && !$this->mode->has(Mode::MAINTENANCEDISABLED) && $moduleName !== 'view') { $module = $this->createModuleInstance(Maintenance::class); } else { // determine the module class and save it to the module instance @@ -535,7 +533,7 @@ class App // Wrapping HTML responses in the theme template if ($response->getHeaderLine(ICanCreateResponses::X_HEADER) === ICanCreateResponses::TYPE_HTML) { - $response = $page->run($this->appHelper, $this->session, $this->baseURL, $this->args, $mode, $response, $this->l10n, $this->profiler, $this->config, $pconfig, $nav, $this->session->getLocalUserId()); + $response = $page->run($this->appHelper, $this->session, $this->baseURL, $this->args, $this->mode, $response, $this->l10n, $this->profiler, $this->config, $pconfig, $nav, $this->session->getLocalUserId()); } $this->logger->debug('Request processed sucessfully', ['response' => $response->getStatusCode(), 'address' => $serverVars['REMOTE_ADDR'] ?? '', 'request' => $requeststring, 'referer' => $serverVars['HTTP_REFERER'] ?? '', 'user-agent' => $serverVars['HTTP_USER_AGENT'] ?? '', 'duration' => number_format(microtime(true) - $request_start, 3)]); From a6c1b2eaf3459b55cb7e477da6e6b7543a62e9fe Mon Sep 17 00:00:00 2001 From: Art4 Date: Wed, 22 Jan 2025 14:59:01 +0000 Subject: [PATCH 19/19] Change BC promise to 5 months, fix some wording --- doc/Developers-Intro.md | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/doc/Developers-Intro.md b/doc/Developers-Intro.md index f07b711648..99e84739d0 100644 --- a/doc/Developers-Intro.md +++ b/doc/Developers-Intro.md @@ -164,7 +164,7 @@ If you are interested in improving those clients, please contact the developers Friendica can be extended by addons. These addons relies on many classes and conventions from Friendica. As developers our work on Friendica should not break things in the addons without giving the addon maintainers a chance to fix their addons. -Our goal is to build trust for the addon maintainers but also allow Friendica developers to move on. +Our goal is to build trust for the addon maintainers but also allow Friendica developers to move on. This is called the Backward Compatibility Promise. Inspired by the [Symonfy BC promise](https://symfony.com/doc/current/contributing/code/bc.html) we promise BC for every class, interface, trait, enum, function, constant, etc., but with the exception of: @@ -208,12 +208,12 @@ As long as the code that is labeled with `@deprecated` is used inside Friendica If the deprecated code is no longer used inside Friendica or the official addons it MUST be hard deprecated. The code MUST NOT be deleted. -Starting from the next release, it MUST be stay for at least 6 months. -Hard deprecated code COULD remain longer than 6 months, depending on when a release appears. -Addon developer MUST NOT consider that they have more than 6 months to adjust their code. +Starting from the next release, it MUST be stay for at least 5 months. +Hard deprecated code COULD remain longer than 5 months, depending on when a release appears. +Addon developer MUST NOT consider that they have more than 5 months to adjust their code. Hard deprecation code means that the code triggers an `E_USER_DEPRECATION` error if it is called. -For instance with the deprecated class `Friendica\Core\Logger` the call of every method should be trigger an error: +For instance with the deprecated class `Friendica\Core\Logger` the call of every method should trigger an error: ```php /** @@ -224,7 +224,7 @@ For instance with the deprecated class `Friendica\Core\Logger` the call of every class Logger { public static function info(string $message, array $context = []) { - trigger_error('Class `' . __CLASS__ . '` is deprecated since 2025.05 and will be removed after 6 months, use constructor injection or `DI::logger()` instead.', E_USER_DEPRECATED); + trigger_error('Class `' . __CLASS__ . '` is deprecated since 2025.05 and will be removed after 5 months, use constructor injection or `DI::logger()` instead.', E_USER_DEPRECATED); self::getInstance()->info($message, $context); } @@ -234,19 +234,19 @@ class Logger { ``` This way the maintainer or users of addons will be notified that the addon will stop working in one of the next releases. -The addon maintainer now has at least 6 months to fix the deprecations. +The addon maintainer now has at least 5 months or at least one release to fix the deprecations. Please note that the deprecation message contains the release that will be released next. -In the example the code was hard deprecated in `2025.05` and COULD be removed earliest with the `2025.11` release. +In the example the code was hard deprecated with release `2025.05`, so it COULD be removed earliest with the `2025.11` release. **3. Code Removing** -We promise BC for deprecated code for at least 6 months, starting from the release the deprecation was announced. +We promise BC for deprecated code for at least 5 months, starting from the release the deprecation was announced. After this time the deprecated code COULD be remove within the next release. Breaking changes MUST be happen only in a new release but MUST be hard deprecated first. The BC promise refers only to releases, respective the `stable` branch. Deprecated code on other branches like `develop` or RC branches could be removed earlier. -This is not a BC break as long as the release is published 6 months after the deprecation. +This is not a BC break as long as the release will be published 5 months after the hard deprecation. -If a release breaks BC without deprecation or earlier than 6 months, this SHOULD considered as a bug and BC SHOULD be restored in a bugfix release. +If a release breaks BC without deprecation or earlier than 5 months, this SHOULD considered as a bug and BC SHOULD be restored in a bugfix release.