diff --git a/_config.php b/_config.php index 6cc0e44db4e..27dcd372a0a 100644 --- a/_config.php +++ b/_config.php @@ -1,6 +1,5 @@ register('embed', [EmbedShortcodeProvider::class, 'handle_shortcode']); - -// Set to 5.0.0 to show APIs marked for removal at that version -Deprecation::notification_version('4.0.0'); diff --git a/_config/i18n.yml b/_config/i18n.yml index a219828b8f8..e900f46f553 100644 --- a/_config/i18n.yml +++ b/_config/i18n.yml @@ -2,14 +2,14 @@ Name: basei18n Before: '#defaulti18n' --- -SilverStripe\i18n\Data\Sources: +SilverStripe\Core\Manifest\ModuleManifest: module_priority: - silverstripe\admin - silverstripe\framework --- Name: defaulti18n --- -SilverStripe\i18n\Data\Sources: +SilverStripe\Core\Manifest\ModuleManifest: module_priority: - other_modules --- diff --git a/src/Control/CookieJar.php b/src/Control/CookieJar.php index 73467526c5a..6c3b0a26c8c 100644 --- a/src/Control/CookieJar.php +++ b/src/Control/CookieJar.php @@ -200,12 +200,9 @@ private function cookieIsSecure(string $sameSite, bool $secure): bool /** * Get the correct samesite value - Session cookies use a different configuration variable. - * - * @deprecated 4.12.0 The relevant methods will include a `$sameSite` parameter instead. */ private function getSameSite(string $name): string { - Deprecation::notice('4.12.0', 'The relevant methods will include a `$sameSite` parameter instead.'); if ($name === session_name()) { return Session::config()->get('cookie_samesite'); } diff --git a/src/Control/Director.php b/src/Control/Director.php index 91023b7a76f..8805612531a 100644 --- a/src/Control/Director.php +++ b/src/Control/Director.php @@ -228,7 +228,7 @@ public static function mockRequest( ? $cookies : Injector::inst()->createWithArgs(Cookie_Backend::class, [$cookies ?: []]); $newVars['_COOKIE'] = $cookieJar->getAll(false); - Cookie::config()->update('report_errors', false); + Cookie::config()->set('report_errors', false); Injector::inst()->registerService($cookieJar, Cookie_Backend::class); // Backup requirements diff --git a/src/Control/Email/Email.php b/src/Control/Email/Email.php index 0cb60a8ac6b..766bf8f7cc7 100644 --- a/src/Control/Email/Email.php +++ b/src/Control/Email/Email.php @@ -268,7 +268,9 @@ public function getSwiftMessage() $message = new Swift_Message(null, null, 'text/html', 'utf-8'); // Set priority to fix PHP 8.1 SimpleMessage::getPriority() sscanf() null parameter $message->setPriority(Swift_Mime_SimpleMessage::PRIORITY_NORMAL); - $this->setSwiftMessage($message); + Deprecation::withNoReplacement(function () use ($message) { + $this->setSwiftMessage($message); + }); } return $this->swiftMessage; @@ -328,7 +330,9 @@ private function getDefaultFrom(): string */ public function getFrom() { - return $this->getSwiftMessage()->getFrom(); + return Deprecation::withNoReplacement(function () { + return $this->getSwiftMessage()->getFrom(); + }); } /** @@ -351,8 +355,9 @@ private function sanitiseAddress($address) public function setFrom($address, $name = null) { $address = $this->sanitiseAddress($address); - $this->getSwiftMessage()->setFrom($address, $name); - + Deprecation::withNoReplacement(function () use ($address, $name) { + $this->getSwiftMessage()->setFrom($address, $name); + }); return $this; } @@ -364,8 +369,9 @@ public function setFrom($address, $name = null) public function addFrom($address, $name = null) { $address = $this->sanitiseAddress($address); - $this->getSwiftMessage()->addFrom($address, $name); - + Deprecation::withNoReplacement(function () use ($address, $name) { + $this->getSwiftMessage()->addFrom($address, $name); + }); return $this; } @@ -374,7 +380,9 @@ public function addFrom($address, $name = null) */ public function getSender() { - return $this->getSwiftMessage()->getSender(); + return Deprecation::withNoReplacement(function () { + return $this->getSwiftMessage()->getSender(); + }); } /** @@ -385,8 +393,9 @@ public function getSender() public function setSender($address, $name = null) { $address = $this->sanitiseAddress($address); - $this->getSwiftMessage()->setSender($address, $name); - + Deprecation::withNoReplacement(function () use ($address, $name) { + $this->getSwiftMessage()->setSender($address, $name); + }); return $this; } @@ -395,7 +404,9 @@ public function setSender($address, $name = null) */ public function getReturnPath() { - return $this->getSwiftMessage()->getReturnPath(); + return Deprecation::withNoReplacement(function () { + return $this->getSwiftMessage()->getReturnPath(); + }); } /** @@ -407,7 +418,9 @@ public function getReturnPath() public function setReturnPath($address) { $address = $this->sanitiseAddress($address); - $this->getSwiftMessage()->setReturnPath($address); + Deprecation::withNoReplacement(function () use ($address) { + $this->getSwiftMessage()->setReturnPath($address); + }); return $this; } @@ -416,7 +429,9 @@ public function setReturnPath($address) */ public function getTo() { - return $this->getSwiftMessage()->getTo(); + return Deprecation::withNoReplacement(function () { + return $this->getSwiftMessage()->getTo(); + }); } /** @@ -432,8 +447,9 @@ public function getTo() public function setTo($address, $name = null) { $address = $this->sanitiseAddress($address); - $this->getSwiftMessage()->setTo($address, $name); - + Deprecation::withNoReplacement(function () use ($address, $name) { + $this->getSwiftMessage()->setTo($address, $name); + }); return $this; } @@ -445,8 +461,9 @@ public function setTo($address, $name = null) public function addTo($address, $name = null) { $address = $this->sanitiseAddress($address); - $this->getSwiftMessage()->addTo($address, $name); - + Deprecation::withNoReplacement(function () use ($address, $name) { + $this->getSwiftMessage()->addTo($address, $name); + }); return $this; } @@ -455,7 +472,9 @@ public function addTo($address, $name = null) */ public function getCC() { - return $this->getSwiftMessage()->getCc(); + return Deprecation::withNoReplacement(function () { + return $this->getSwiftMessage()->getCc(); + }); } /** @@ -466,8 +485,9 @@ public function getCC() public function setCC($address, $name = null) { $address = $this->sanitiseAddress($address); - $this->getSwiftMessage()->setCc($address, $name); - + Deprecation::withNoReplacement(function () use ($address, $name) { + $this->getSwiftMessage()->setCc($address, $name); + }); return $this; } @@ -479,8 +499,9 @@ public function setCC($address, $name = null) public function addCC($address, $name = null) { $address = $this->sanitiseAddress($address); - $this->getSwiftMessage()->addCc($address, $name); - + Deprecation::withNoReplacement(function () use ($address, $name) { + $this->getSwiftMessage()->addCc($address, $name); + }); return $this; } @@ -489,7 +510,9 @@ public function addCC($address, $name = null) */ public function getBCC() { - return $this->getSwiftMessage()->getBcc(); + return Deprecation::withNoReplacement(function () { + return $this->getSwiftMessage()->getBcc(); + }); } /** @@ -500,8 +523,9 @@ public function getBCC() public function setBCC($address, $name = null) { $address = $this->sanitiseAddress($address); - $this->getSwiftMessage()->setBcc($address, $name); - + Deprecation::withNoReplacement(function () use ($address, $name) { + $this->getSwiftMessage()->setBcc($address, $name); + }); return $this; } @@ -513,8 +537,9 @@ public function setBCC($address, $name = null) public function addBCC($address, $name = null) { $address = $this->sanitiseAddress($address); - $this->getSwiftMessage()->addBcc($address, $name); - + Deprecation::withNoReplacement(function () use ($address, $name) { + $this->getSwiftMessage()->addBcc($address, $name); + }); return $this; } @@ -523,7 +548,9 @@ public function addBCC($address, $name = null) */ public function getReplyTo() { - return $this->getSwiftMessage()->getReplyTo(); + return Deprecation::withNoReplacement(function () { + return $this->getSwiftMessage()->getReplyTo(); + }); } /** @@ -534,8 +561,9 @@ public function getReplyTo() public function setReplyTo($address, $name = null) { $address = $this->sanitiseAddress($address); - $this->getSwiftMessage()->setReplyTo($address, $name); - + Deprecation::withNoReplacement(function () use ($address, $name) { + $this->getSwiftMessage()->setReplyTo($address, $name); + }); return $this; } @@ -547,8 +575,9 @@ public function setReplyTo($address, $name = null) public function addReplyTo($address, $name = null) { $address = $this->sanitiseAddress($address); - $this->getSwiftMessage()->addReplyTo($address, $name); - + Deprecation::withNoReplacement(function () use ($address, $name) { + $this->getSwiftMessage()->addReplyTo($address, $name); + }); return $this; } @@ -557,7 +586,9 @@ public function addReplyTo($address, $name = null) */ public function getSubject() { - return $this->getSwiftMessage()->getSubject(); + return Deprecation::withNoReplacement(function () { + return $this->getSwiftMessage()->getSubject(); + }); } /** @@ -566,8 +597,9 @@ public function getSubject() */ public function setSubject($subject) { - $this->getSwiftMessage()->setSubject($subject); - + Deprecation::withNoReplacement(function () use ($subject) { + $this->getSwiftMessage()->setSubject($subject); + }); return $this; } @@ -576,7 +608,9 @@ public function setSubject($subject) */ public function getPriority() { - return $this->getSwiftMessage()->getPriority(); + return Deprecation::withNoReplacement(function () { + return $this->getSwiftMessage()->getPriority(); + }); } /** @@ -585,8 +619,9 @@ public function getPriority() */ public function setPriority($priority) { - $this->getSwiftMessage()->setPriority($priority); - + Deprecation::withNoReplacement(function () use ($priority) { + $this->getSwiftMessage()->setPriority($priority); + }); return $this; } @@ -622,8 +657,9 @@ public function addAttachmentFromData($data, $name, $mime = null) if ($mime) { $attachment->setContentType($mime); } - $this->getSwiftMessage()->attach($attachment); - + Deprecation::withNoReplacement(function () use ($attachment) { + $this->getSwiftMessage()->attach($attachment); + }); return $this; } @@ -642,8 +678,9 @@ public function getData() public function setData($data) { $this->data = $data; - $this->invalidateBody(); - + Deprecation::withNoReplacement(function () { + $this->invalidateBody(); + }); return $this; } @@ -661,9 +698,9 @@ public function addData($name, $value = null) } else { $this->data->$name = $value; } - - $this->invalidateBody(); - + Deprecation::withNoReplacement(function () { + $this->invalidateBody(); + }); return $this; } @@ -680,9 +717,9 @@ public function removeData($name) } else { $this->data->$name = null; } - - $this->invalidateBody(); - + Deprecation::withNoReplacement(function () { + $this->invalidateBody(); + }); return $this; } @@ -691,7 +728,9 @@ public function removeData($name) */ public function getBody() { - return $this->getSwiftMessage()->getBody(); + return Deprecation::withNoReplacement(function () { + return $this->getSwiftMessage()->getBody(); + }); } /** @@ -700,15 +739,16 @@ public function getBody() */ public function setBody($body) { - $plainPart = $this->findPlainPart(); - if ($plainPart) { - $this->getSwiftMessage()->detach($plainPart); - } - unset($plainPart); - - $body = HTTP::absoluteURLs($body); - $this->getSwiftMessage()->setBody($body); - + Deprecation::withNoReplacement(function () use ($body) { + $plainPart = $this->findPlainPart(); + if ($plainPart) { + $this->getSwiftMessage()->detach($plainPart); + } + unset($plainPart); + + $body = HTTP::absoluteURLs($body); + $this->getSwiftMessage()->setBody($body); + }); return $this; } @@ -746,10 +786,11 @@ public function BaseURL() public function debug() { Deprecation::notice('4.12.0', 'Will be removed without equivalent functionality to replace it'); - $this->render(); - - $class = static::class; - return "
' . $this->getSwiftMessage()->toString() . ''; + return Deprecation::withNoReplacement(function () { + $this->render(); + $class = static::class; + return "
' . $this->getSwiftMessage()->toString() . ''; + }); } /** @@ -854,13 +895,15 @@ public function IsEmail() */ public function send() { - if (!$this->getBody()) { - $this->render(); - } - if (!$this->hasPlainPart()) { - $this->generatePlainPartFromBody(); - } - return Injector::inst()->get(Mailer::class)->send($this); + return Deprecation::withNoReplacement(function () { + if (!$this->getBody()) { + $this->render(); + } + if (!$this->hasPlainPart()) { + $this->generatePlainPartFromBody(); + } + return Injector::inst()->get(Mailer::class)->send($this); + }); } /** @@ -868,10 +911,12 @@ public function send() */ public function sendPlain() { - if (!$this->hasPlainPart()) { - $this->render(true); - } - return Injector::inst()->get(Mailer::class)->send($this); + return Deprecation::withNoReplacement(function () { + if (!$this->hasPlainPart()) { + $this->render(true); + } + return Injector::inst()->get(Mailer::class)->send($this); + }); } /** @@ -884,68 +929,71 @@ public function sendPlain() public function render($plainOnly = false) { Deprecation::notice('4.12.0', 'Will be removed without equivalent functionality to replace it'); + return Deprecation::withNoReplacement(function () use ($plainOnly) { + $existingPlainPart = Deprecation::withNoReplacement(function () { + return $this->findPlainPart(); + }); + if ($existingPlainPart) { + $this->getSwiftMessage()->detach($existingPlainPart); + } + unset($existingPlainPart); - if ($existingPlainPart = $this->findPlainPart()) { - $this->getSwiftMessage()->detach($existingPlainPart); - } - unset($existingPlainPart); - - // Respect explicitly set body - $htmlPart = $plainOnly ? null : $this->getBody(); - $plainPart = $plainOnly ? $this->getBody() : null; + // Respect explicitly set body + $htmlPart = $plainOnly ? null : $this->getBody(); + $plainPart = $plainOnly ? $this->getBody() : null; - // Ensure we can at least render something - $htmlTemplate = $this->getHTMLTemplate(); - $plainTemplate = $this->getPlainTemplate(); - if (!$htmlTemplate && !$plainTemplate && !$plainPart && !$htmlPart) { - return $this; - } + // Ensure we can at least render something + $htmlTemplate = $this->getHTMLTemplate(); + $plainTemplate = $this->getPlainTemplate(); + if (!$htmlTemplate && !$plainTemplate && !$plainPart && !$htmlPart) { + return $this; + } - // Do not interfere with emails styles - Requirements::clear(); + // Do not interfere with emails styles + Requirements::clear(); - // Render plain part - if ($plainTemplate && !$plainPart) { - $plainPart = $this->renderWith($plainTemplate, $this->getData())->Plain(); - } - - // Render HTML part, either if sending html email, or a plain part is lacking - if (!$htmlPart && $htmlTemplate && (!$plainOnly || empty($plainPart))) { - $htmlPart = $this->renderWith($htmlTemplate, $this->getData()); - } + // Render plain part + if ($plainTemplate && !$plainPart) { + $plainPart = $this->renderWith($plainTemplate, $this->getData())->Plain(); + } - // Plain part fails over to generated from html - if (!$plainPart && $htmlPart) { - /** @var DBHTMLText $htmlPartObject */ - $htmlPartObject = DBField::create_field('HTMLFragment', $htmlPart); - $plainPart = $htmlPartObject->Plain(); - } + // Render HTML part, either if sending html email, or a plain part is lacking + if (!$htmlPart && $htmlTemplate && (!$plainOnly || empty($plainPart))) { + $htmlPart = $this->renderWith($htmlTemplate, $this->getData()); + } - // Rendering is finished - Requirements::restore(); + // Plain part fails over to generated from html + if (!$plainPart && $htmlPart) { + /** @var DBHTMLText $htmlPartObject */ + $htmlPartObject = DBField::create_field('HTMLFragment', $htmlPart); + $plainPart = $htmlPartObject->Plain(); + } - // Fail if no email to send - if (!$plainPart && !$htmlPart) { - return $this; - } + // Rendering is finished + Requirements::restore(); - // Build HTML / Plain components - if ($htmlPart && !$plainOnly) { - $this->setBody($htmlPart); - $this->getSwiftMessage()->setContentType('text/html'); - $this->getSwiftMessage()->setCharset('utf-8'); - if ($plainPart) { - $this->getSwiftMessage()->addPart($plainPart, 'text/plain', 'utf-8'); + // Fail if no email to send + if (!$plainPart && !$htmlPart) { + return $this; } - } else { - if ($plainPart) { - $this->setBody($plainPart); - } - $this->getSwiftMessage()->setContentType('text/plain'); - $this->getSwiftMessage()->setCharset('utf-8'); - } - return $this; + // Build HTML / Plain components + if ($htmlPart && !$plainOnly) { + $this->setBody($htmlPart); + $this->getSwiftMessage()->setContentType('text/html'); + $this->getSwiftMessage()->setCharset('utf-8'); + if ($plainPart) { + $this->getSwiftMessage()->addPart($plainPart, 'text/plain', 'utf-8'); + } + } else { + if ($plainPart) { + $this->setBody($plainPart); + } + $this->getSwiftMessage()->setContentType('text/plain'); + $this->getSwiftMessage()->setCharset('utf-8'); + } + return $this; + }); } /** @@ -956,12 +1004,14 @@ public function render($plainOnly = false) public function findPlainPart() { Deprecation::notice('4.12.0', 'Will be removed without equivalent functionality to replace it'); - foreach ($this->getSwiftMessage()->getChildren() as $child) { - if ($child instanceof Swift_MimePart && $child->getContentType() == 'text/plain') { - return $child; + return Deprecation::withNoReplacement(function () { + foreach ($this->getSwiftMessage()->getChildren() as $child) { + if ($child instanceof Swift_MimePart && $child->getContentType() == 'text/plain') { + return $child; + } } - } - return false; + return false; + }); } /** @@ -972,10 +1022,12 @@ public function findPlainPart() public function hasPlainPart() { Deprecation::notice('4.12.0', 'Will be removed without equivalent functionality to replace it'); - if ($this->getSwiftMessage()->getContentType() === 'text/plain') { - return true; - } - return (bool) $this->findPlainPart(); + return Deprecation::withNoReplacement(function () { + if ($this->getSwiftMessage()->getContentType() === 'text/plain') { + return true; + } + return (bool) $this->findPlainPart(); + }); } /** @@ -988,18 +1040,19 @@ public function hasPlainPart() public function generatePlainPartFromBody() { Deprecation::notice('4.12.0', 'Will be removed without equivalent functionality to replace it'); - $plainPart = $this->findPlainPart(); - if ($plainPart) { - $this->getSwiftMessage()->detach($plainPart); - } - unset($plainPart); - - $this->getSwiftMessage()->addPart( - Convert::xml2raw($this->getBody()), - 'text/plain', - 'utf-8' - ); + return Deprecation::withNoReplacement(function () { + $plainPart = $this->findPlainPart(); + if ($plainPart) { + $this->getSwiftMessage()->detach($plainPart); + } + unset($plainPart); - return $this; + $this->getSwiftMessage()->addPart( + Convert::xml2raw($this->getBody()), + 'text/plain', + 'utf-8' + ); + return $this; + }); } } diff --git a/src/Control/Email/SwiftMailer.php b/src/Control/Email/SwiftMailer.php index 33371acdc21..3afca409bda 100644 --- a/src/Control/Email/SwiftMailer.php +++ b/src/Control/Email/SwiftMailer.php @@ -40,7 +40,9 @@ class SwiftMailer implements Mailer */ public function __construct() { - Deprecation::notice('4.12.0', 'Will be replaced with symfony/mailer', Deprecation::SCOPE_CLASS); + Deprecation::withNoReplacement(function () { + Deprecation::notice('4.12.0', 'Will be replaced with symfony/mailer', Deprecation::SCOPE_CLASS); + }); } public function send($message) diff --git a/src/Control/Email/SwiftPlugin.php b/src/Control/Email/SwiftPlugin.php index 277c4f18ba4..5e53e8a3efc 100644 --- a/src/Control/Email/SwiftPlugin.php +++ b/src/Control/Email/SwiftPlugin.php @@ -11,7 +11,9 @@ class SwiftPlugin implements \Swift_Events_SendListener { public function __construct() { - Deprecation::notice('4.12.0', 'Will be replaced with symfony/mailer', Deprecation::SCOPE_CLASS); + Deprecation::withNoReplacement(function () { + Deprecation::notice('4.12.0', 'Will be replaced with symfony/mailer', Deprecation::SCOPE_CLASS); + }); } /** diff --git a/src/Control/HTTP.php b/src/Control/HTTP.php index 84fce924daa..cce77aec48a 100644 --- a/src/Control/HTTP.php +++ b/src/Control/HTTP.php @@ -126,7 +126,7 @@ public static function absoluteURLs($html) if (preg_match('/^\w+:/', $url ?? '')) { return $url; } - return Director::absoluteURL($url, true); + return Director::absoluteURL($url); }); } @@ -474,6 +474,8 @@ public static function add_cache_headers($response = null) * Ensure that all deprecated HTTP cache settings are respected * * @deprecated 4.2.0 Use HTTPCacheControlMiddleware instead + * Simply delete this method in CMS 5 and the calls to it from HTTPCacheControlMiddleware + * * @throws \LogicException * @param HTTPRequest $request * @param HTTPResponse $response @@ -491,32 +493,32 @@ public static function augmentState(HTTPRequest $request, HTTPResponse $response // if http caching is disabled by config, disable it - used on dev environments due to frequently changing // templates and other data. will be overridden by forced publicCache(true) or privateCache(true) calls - if ($config->get('disable_http_cache')) { - Deprecation::notice('5.0', 'Use HTTPCacheControlMiddleware.defaultState/.defaultForcingLevel instead'); - $cacheControlMiddleware->disableCache(); - } + Deprecation::withNoReplacement(function () use ($config, $cacheControlMiddleware) { + if ($config->get('disable_http_cache')) { + $cacheControlMiddleware->disableCache(); + } + }); // if no caching ajax requests, disable ajax if is ajax request - if (!$config->get('cache_ajax_requests') && Director::is_ajax()) { - Deprecation::notice( - '5.0', - 'HTTP.cache_ajax_requests config is deprecated. Use HTTPCacheControlMiddleware::disableCache() instead' - ); - $cacheControlMiddleware->disableCache(); - } + Deprecation::withNoReplacement(function () use ($config, $cacheControlMiddleware) { + if (!$config->get('cache_ajax_requests') && Director::is_ajax()) { + $cacheControlMiddleware->disableCache(); + } + }); // Pass vary to middleware - $configVary = $config->get('vary'); + $configVary = Deprecation::withNoReplacement(function () use ($config) { + return $config->get('vary'); + }); if ($configVary) { - Deprecation::notice('5.0', 'Use HTTPCacheControlMiddleware.defaultVary instead'); $cacheControlMiddleware->addVary($configVary); } // Pass cache_control to middleware - $configCacheControl = $config->get('cache_control'); + $configCacheControl = Deprecation::withNoReplacement(function () use ($config) { + return $config->get('cache_control'); + }); if ($configCacheControl) { - Deprecation::notice('5.0', 'Use HTTPCacheControlMiddleware API instead'); - $supportedDirectives = ['max-age', 'no-cache', 'no-store', 'must-revalidate']; if ($foundUnsupported = array_diff(array_keys($configCacheControl ?? []), $supportedDirectives)) { throw new \LogicException( diff --git a/src/Control/Middleware/FlushMiddleware.php b/src/Control/Middleware/FlushMiddleware.php index e3bd61fbebb..98b49423b12 100644 --- a/src/Control/Middleware/FlushMiddleware.php +++ b/src/Control/Middleware/FlushMiddleware.php @@ -2,10 +2,12 @@ namespace SilverStripe\Control\Middleware; -use SilverStripe\Control\Director; use SilverStripe\Control\HTTPRequest; +use SilverStripe\Core\BaseKernel; use SilverStripe\Core\ClassInfo; use SilverStripe\Core\Flushable; +use SilverStripe\Core\Injector\Injector; +use SilverStripe\Core\Kernel; /** * Triggers a call to flush() on all implementors of Flushable. @@ -14,7 +16,9 @@ class FlushMiddleware implements HTTPMiddleware { public function process(HTTPRequest $request, callable $delegate) { - if (Director::isManifestFlushed()) { + /** @var BaseKernel $kernel */ + $kernel = Injector::inst()->get(Kernel::class); + if ((method_exists($kernel, 'isFlushed') && $kernel->isFlushed())) { // Disable cache when flushing HTTPCacheControlMiddleware::singleton()->disableCache(true); diff --git a/src/Control/Middleware/HTTPCacheControlMiddleware.php b/src/Control/Middleware/HTTPCacheControlMiddleware.php index 4f7aa49c6fa..403007a3491 100644 --- a/src/Control/Middleware/HTTPCacheControlMiddleware.php +++ b/src/Control/Middleware/HTTPCacheControlMiddleware.php @@ -4,14 +4,15 @@ use InvalidArgumentException; use SilverStripe\Control\HTTP; +use SilverStripe\Core\Resettable; +use SilverStripe\Dev\Deprecation; use SilverStripe\Control\HTTPRequest; use SilverStripe\Control\HTTPResponse; -use SilverStripe\Control\HTTPResponse_Exception; +use SilverStripe\Core\Injector\Injector; use SilverStripe\Core\Config\Configurable; use SilverStripe\Core\Injector\Injectable; -use SilverStripe\Core\Injector\Injector; -use SilverStripe\Core\Resettable; use SilverStripe\ORM\FieldType\DBDatetime; +use SilverStripe\Control\HTTPResponse_Exception; class HTTPCacheControlMiddleware implements HTTPMiddleware, Resettable { @@ -51,7 +52,9 @@ public function process(HTTPRequest $request, callable $delegate) $this->augmentState($request, $response); // Update state based on deprecated HTTP settings - HTTP::augmentState($request, $response); + Deprecation::withNoReplacement(function () use ($request, $response) { + HTTP::augmentState($request, $response); + }); // Add all headers to this response object $this->applyToResponse($response); diff --git a/src/Control/Middleware/URLSpecialsMiddleware/FlushScheduler.php b/src/Control/Middleware/URLSpecialsMiddleware/FlushScheduler.php index 6f189286edc..f2b62d0c267 100644 --- a/src/Control/Middleware/URLSpecialsMiddleware/FlushScheduler.php +++ b/src/Control/Middleware/URLSpecialsMiddleware/FlushScheduler.php @@ -2,10 +2,10 @@ namespace SilverStripe\Control\Middleware\URLSpecialsMiddleware; +use SilverStripe\Core\BaseKernel; use SilverStripe\Core\Kernel; use SilverStripe\Core\Injector\Injector; use SilverStripe\Core\Startup\ScheduledFlushDiscoverer; -use SilverStripe\Control\Director; use SilverStripe\Control\HTTPRequest; /** @@ -30,11 +30,12 @@ public function scheduleFlush(HTTPRequest $request) { $flush = array_key_exists('flush', $request->getVars() ?? []) || ($request->getURL() === 'dev/build'); - if (!$flush || Director::isManifestFlushed()) { + /** @var BaseKernel $kernel */ + $kernel = Injector::inst()->get(Kernel::class); + if (!$flush || (method_exists($kernel, 'isFlushed') && $kernel->isFlushed())) { return false; } - $kernel = Injector::inst()->get(Kernel::class); ScheduledFlushDiscoverer::scheduleFlush($kernel); return true; diff --git a/src/Control/RSS/RSSFeed.php b/src/Control/RSS/RSSFeed.php index fd35b617ed5..5ab5eae9b74 100644 --- a/src/Control/RSS/RSSFeed.php +++ b/src/Control/RSS/RSSFeed.php @@ -222,7 +222,7 @@ public function Description() public function outputToBrowser() { $prevState = SSViewer::config()->uninherited('source_file_comments'); - SSViewer::config()->update('source_file_comments', false); + SSViewer::config()->set('source_file_comments', false); $response = Controller::curr()->getResponse(); @@ -236,7 +236,7 @@ public function outputToBrowser() $response->addHeader("Content-Type", "application/rss+xml; charset=utf-8"); - SSViewer::config()->update('source_file_comments', $prevState); + SSViewer::config()->set('source_file_comments', $prevState); return $this->renderWith($this->getTemplates()); } diff --git a/src/Control/RequestProcessor.php b/src/Control/RequestProcessor.php index 0661fcddae5..f8ef07623d2 100644 --- a/src/Control/RequestProcessor.php +++ b/src/Control/RequestProcessor.php @@ -29,7 +29,9 @@ class RequestProcessor implements HTTPMiddleware */ public function __construct($filters = []) { - Deprecation::notice('4.0.1', 'Use HTTPMiddleware directly instead.', Deprecation::SCOPE_CLASS); + Deprecation::withNoReplacement(function () { + Deprecation::notice('4.0.1', 'Use HTTPMiddleware directly instead.', Deprecation::SCOPE_CLASS); + }); $this->filters = $filters; } diff --git a/src/Control/Session.php b/src/Control/Session.php index 01623d87f71..5d49b92b336 100644 --- a/src/Control/Session.php +++ b/src/Control/Session.php @@ -586,13 +586,11 @@ public function save(HTTPRequest $request) * Recursively apply the changes represented in $data to $dest. * Used to update $_SESSION * - * @deprecated 4.1.0 Use recursivelyApplyChanges() instead * @param array $data * @param array $dest */ protected function recursivelyApply($data, &$dest) { - Deprecation::notice('4.1.0', 'Use recursivelyApplyChanges() instead'); foreach ($data as $k => $v) { if (is_array($v)) { if (!isset($dest[$k]) || !is_array($dest[$k])) { diff --git a/src/Control/SimpleResourceURLGenerator.php b/src/Control/SimpleResourceURLGenerator.php index e6ea62175a4..40bd6189dc4 100644 --- a/src/Control/SimpleResourceURLGenerator.php +++ b/src/Control/SimpleResourceURLGenerator.php @@ -82,7 +82,10 @@ public function urlForResource($relativePath) // Determine lookup mechanism based on existence of public/ folder. // From 5.0 onwards only resolvePublicResource() will be used. if (!Director::publicDir()) { - list($exists, $absolutePath, $relativePath) = $this->resolveUnsecuredResource($relativePath); + $ret = Deprecation::withNoReplacement(function () use ($relativePath) { + return $this->resolveUnsecuredResource($relativePath); + }); + list($exists, $absolutePath, $relativePath) = $ret; } else { list($exists, $absolutePath, $relativePath) = $this->resolvePublicResource($relativePath); } diff --git a/src/Core/BaseKernel.php b/src/Core/BaseKernel.php index ee3370d54ad..3706f94d675 100644 --- a/src/Core/BaseKernel.php +++ b/src/Core/BaseKernel.php @@ -180,18 +180,24 @@ protected function bootPHP() protected function bootManifests($flush) { // Setup autoloader - $this->getClassLoader()->init( - $this->getIncludeTests(), - $flush, - $this->getIgnoredCIConfigs() - ); - - // Find modules - $this->getModuleLoader()->init( - $this->getIncludeTests(), - $flush, - $this->getIgnoredCIConfigs() - ); + $ignoredCIConfigs = Deprecation::withNoReplacement(function () { + return $this->getIgnoredCIConfigs(); + }); + + Deprecation::withNoReplacement(function () use ($flush, $ignoredCIConfigs) { + $this->getClassLoader()->init( + $this->getIncludeTests(), + $flush, + $ignoredCIConfigs + ); + + // Find modules + $this->getModuleLoader()->init( + $this->getIncludeTests(), + $flush, + $ignoredCIConfigs + ); + }); // Flush config if ($flush) { @@ -209,11 +215,13 @@ protected function bootManifests($flush) $defaultSet->setProject( ModuleManifest::config()->get('project') ); - $defaultSet->init( - $this->getIncludeTests(), - $flush, - $this->getIgnoredCIConfigs() - ); + Deprecation::withNoReplacement(function () use ($defaultSet, $flush, $ignoredCIConfigs) { + $defaultSet->init( + $this->getIncludeTests(), + $flush, + $ignoredCIConfigs + ); + }); } } @@ -259,12 +267,9 @@ protected function bootErrorHandling() * Get the environment type * * @return string - * - * @deprecated 4.12.0 Use Director::get_environment_type() instead */ public function getEnvironment() { - Deprecation::notice('4.12.0', 'Use Director::get_environment_type() instead'); // Check set if ($this->enviroment) { return $this->enviroment; @@ -288,12 +293,9 @@ public function getEnvironment() * Check or update any temporary environment specified in the session. * * @return null|string - * - * @deprecated 4.12.0 Use Director::get_session_environment_type() instead */ protected function sessionEnvironment() { - Deprecation::notice('4.12.0', 'Use Director::get_session_environment_type() instead'); if (!$this->booted) { // session is not initialyzed yet, neither is manifest return null; diff --git a/src/Core/Convert.php b/src/Core/Convert.php index 0fb4293c16a..2021e844662 100644 --- a/src/Core/Convert.php +++ b/src/Core/Convert.php @@ -275,7 +275,7 @@ public static function json2obj($val) /** * Convert a JSON string into an array. * - * @deprecated 4.4.0 Use json_decode() instead + * @deprecated 4.4.0 Use json_decode($val, true) instead * @param string $val JSON string to convert * @return array|boolean */ diff --git a/src/Core/Manifest/ClassLoader.php b/src/Core/Manifest/ClassLoader.php index 238fa647f2e..ac562dcd255 100644 --- a/src/Core/Manifest/ClassLoader.php +++ b/src/Core/Manifest/ClassLoader.php @@ -131,7 +131,9 @@ public function init($includeTests = false, $forceRegen = false, array $ignoredC foreach ($this->manifests as $manifest) { /** @var ClassManifest $instance */ $instance = $manifest['instance']; - $instance->init($includeTests, $forceRegen, $ignoredCIConfigs); + Deprecation::withNoReplacement(function () use ($instance, $includeTests, $forceRegen, $ignoredCIConfigs) { + $instance->init($includeTests, $forceRegen, $ignoredCIConfigs); + }); } $this->registerAutoloader(); diff --git a/src/Core/Manifest/ClassManifest.php b/src/Core/Manifest/ClassManifest.php index 7ebdc0dfe95..7bd40730461 100644 --- a/src/Core/Manifest/ClassManifest.php +++ b/src/Core/Manifest/ClassManifest.php @@ -297,7 +297,9 @@ public function init($includeTests = false, $forceRegen = false, array $ignoredC } // Build - $this->regenerate($includeTests, $ignoredCIConfigs); + Deprecation::withNoReplacement(function () use ($includeTests, $ignoredCIConfigs) { + $this->regenerate($includeTests, $ignoredCIConfigs); + }); } /** diff --git a/src/Core/Manifest/ManifestFileFinder.php b/src/Core/Manifest/ManifestFileFinder.php index 75763e4ed65..9011a51e82c 100644 --- a/src/Core/Manifest/ManifestFileFinder.php +++ b/src/Core/Manifest/ManifestFileFinder.php @@ -4,6 +4,7 @@ use RuntimeException; use SilverStripe\Assets\FileFinder; +use SilverStripe\Dev\Deprecation; /** * An extension to the default file finder with some extra filters to facilitate @@ -285,7 +286,9 @@ private function findModuleCIPhpConfiguration(string $basename, string $pathname if ($this->isDirectoryModule($newBasename, $newPathname, $newDepth)) { // We've reached the root of the module folder, we can read the PHP CI config now $module = new Module($newPathname, $this->upLevels($newPathname, $newDepth)); - $config = $module->getCIConfig(); + $config = Deprecation::withNoReplacement(function () use ($module) { + return $module->getCIConfig(); + }); if (empty($config['PHP'])) { // This should never happen diff --git a/src/Dev/Deprecation.php b/src/Dev/Deprecation.php index 5bd17cda6d0..3ca6a0d3be2 100644 --- a/src/Dev/Deprecation.php +++ b/src/Dev/Deprecation.php @@ -5,6 +5,7 @@ use BadMethodCallException; use SilverStripe\Control\Director; use SilverStripe\Core\Environment; +use SilverStripe\Core\Injector\InjectionCreator; use SilverStripe\Core\Injector\InjectorLoader; use SilverStripe\Core\Manifest\Module; @@ -21,19 +22,7 @@ * * This class abstracts the above pattern and adds a way to do that. * - * Each call to notice passes a version that the notice will be valid from. Additionally this class has a notion of the - * version it should use when deciding whether to raise the notice. If that version is equal to or greater than the - * notices version (and SilverStripe is in dev mode) a deprecation message will be raised. - * - * Normally the checking version will be the release version of SilverStripe, but a developer can choose to set it to a - * future version, to see how their code will behave in future versions. - * - * Modules can also set the version for calls they make - either setting it to a future version in order to ensure - * forwards compatibility or setting it backwards if a module has not yet removed references to deprecated methods. - * - * When set per-module, only direct calls to deprecated methods from those modules are considered - if the module - * calls a non-module method which then calls a deprecated method, that call will use the global check version, not - * the module specific check version. + * Each call to notice passes a version that the notice will be valid from. */ class Deprecation { @@ -58,10 +47,22 @@ class Deprecation * must be available before this to avoid infinite loops. * * @var boolean|null - * @deprecated 4.12.0 Use $is_enabled instead + * @deprecated 4.12.0 Use $currentlyEnabled instead */ protected static $enabled = null; + /** + * @var array + * @deprecated 4.12.0 Will be removed without equivalent functionality to replace it + */ + protected static $module_version_overrides = []; + + /** + * @var array + * @deprecated 4.12.0 Will be removed without equivalent functionality to replace it + */ + public static $notice_level = E_USER_DEPRECATED; + /** * Must be configured outside of the config API, as deprecation API * must be available before this to avoid infinite loops. @@ -70,48 +71,64 @@ class Deprecation * * @internal - Marked as internal so this and other private static's are not treated as config */ - private static bool $is_enabled = false; + private static bool $currentlyEnabled = false; /** - * @var array - * @deprecated 4.12.0 Will be removed without equivalent functionality to replace it + * @internal */ - protected static $module_version_overrides = []; + private static bool $insideNotice = false; /** * @internal */ - private static bool $inside_notice = false; + private static bool $insideWithNoReplacement = false; /** - * @var array - * @deprecated 4.12.0 Will be removed without equivalent functionality to replace it + * Buffer of user_errors to be raised + * + * @internal */ - public static $notice_level = E_USER_DEPRECATED; + private static array $userErrorMessageBuffer = []; + + /** + * @internal + */ + private static bool $haveSetShutdownFunction = false; /** - * Buffer of user_errors to be raised when enabled() is called - * - * This is used when setting deprecated config via yaml, before Deprecation::enable() has been called in _config.php - * Deprecated config set via yaml will only be shown in the browser when using ?flush=1 - * It will not show in CLI when running dev/build flush=1 - * * @internal */ - private static array $user_error_message_buffer = []; + private static bool $showNoReplacementNotices = false; - public static function enable(): void + public static function enable(bool $showNoReplacementNotices = false): void { - static::$is_enabled = true; - foreach (self::$user_error_message_buffer as $message) { - user_error($message, E_USER_DEPRECATED); - } - self::$user_error_message_buffer = []; + static::$currentlyEnabled = true; + static::$showNoReplacementNotices = $showNoReplacementNotices; } public static function disable(): void { - static::$is_enabled = false; + static::$currentlyEnabled = false; + } + + /** + * Used to wrap deprecated methods and deprecated config get()/set() that will be removed + * in the next major version with no replacement. This is done to surpress deprecation notices + * by for calls from the vendor dir to deprecated code that projects have no ability to change + * + * @return mixed + */ + public static function withNoReplacement(callable $func) + { + if (self::$insideWithNoReplacement) { + return $func(); + } + self::$insideWithNoReplacement = true; + try { + return $func(); + } finally { + self::$insideWithNoReplacement = false; + } } /** @@ -159,12 +176,19 @@ protected static function get_called_method_from_trace($backtrace, $level = 1) if (!$level) { $level = 1; } - $called = $backtrace ? $backtrace[$level] : []; - - if (isset($called['class'])) { - return $called['class'] . $called['type'] . $called['function']; + $newLevel = $level; + // handle call_user_func + if ($level === 4 && strpos($backtrace[2]['function'] ?? '', 'call_user_func') !== false) { + $newLevel = 5; + } elseif (strpos($backtrace[$level]['function'] ?? '', 'call_user_func') !== false) { + $newLevel = $level + 1; + } + // handle InjectionCreator + if ($level == 4 && ($backtrace[$newLevel]['class'] ?? '') === InjectionCreator::class) { + $newLevel = $newLevel + 4; } - return $called['function'] ?? ''; + $called = $backtrace[$newLevel] ?? []; + return ($called['class'] ?? '') . ($called['type'] ?? '') . ($called['function'] ?? ''); } /** @@ -179,12 +203,12 @@ public static function get_enabled() // noop } - private static function get_is_enabled(): bool + public static function isEnabled(): bool { if (!Director::isDev()) { return false; } - return static::$is_enabled || Environment::getEnv('SS_DEPRECATION_ENABLED'); + return static::$currentlyEnabled || Environment::getEnv('SS_DEPRECATION_ENABLED'); } /** @@ -199,6 +223,24 @@ public static function set_enabled($enabled) // noop } + public static function outputNotices(): void + { + if (!self::isEnabled()) { + return; + } + // using a while loop with array_shift() to ensure that self::$userErrorMessageBuffer will have + // have values removed from it before calling user_error() + while (count(self::$userErrorMessageBuffer)) { + $arr = array_shift(self::$userErrorMessageBuffer); + $message = $arr['message']; + $calledInsideWithNoReplacement = $arr['calledInsideWithNoReplacement']; + if ($calledInsideWithNoReplacement && !self::$showNoReplacementNotices) { + continue; + } + user_error($message, E_USER_DEPRECATED); + } + } + /** * Raise a notice indicating the method is deprecated if the version passed as the second argument is greater * than or equal to the check version set via ::notification_version @@ -209,22 +251,23 @@ public static function set_enabled($enabled) */ public static function notice($atVersion, $string = '', $scope = Deprecation::SCOPE_METHOD) { - if (static::$inside_notice) { + if (static::$insideNotice) { return; } - static::$inside_notice = true; + static::$insideNotice = true; // try block needs to wrap all code in case anything inside the try block // calls something else that calls Deprecation::notice() try { if ($scope === self::SCOPE_CONFIG) { - if (self::get_is_enabled()) { - user_error($string, E_USER_DEPRECATED); - } else { - self::$user_error_message_buffer[] = $string; - } + // Deprecated config set via yaml will only be shown in the browser when using ?flush=1 + // It will not show in CLI when running dev/build flush=1 + self::$userErrorMessageBuffer[] = [ + 'message' => $string, + 'calledInsideWithNoReplacement' => self::$insideWithNoReplacement + ]; } else { - if (!self::get_is_enabled()) { - // Do not add to self::$user_error_message_buffer, as the backtrace is too expensive + if (!self::isEnabled()) { + // Do not add to self::$userErrorMessageBuffer, as the backtrace is too expensive return; } @@ -234,7 +277,7 @@ public static function notice($atVersion, $string = '', $scope = Deprecation::SC // Get the calling scope if ($scope == Deprecation::SCOPE_METHOD) { $backtrace = debug_backtrace(0); - $caller = self::get_called_method_from_trace($backtrace); + $caller = self::get_called_method_from_trace($backtrace, 1); } elseif ($scope == Deprecation::SCOPE_CLASS) { $backtrace = debug_backtrace(0); $caller = isset($backtrace[1]['class']) ? $backtrace[1]['class'] : '(unknown)'; @@ -242,18 +285,30 @@ public static function notice($atVersion, $string = '', $scope = Deprecation::SC $caller = false; } - // Then raise the notice if (substr($string, -1) != '.') { $string .= "."; } - $string .= " Called from " . self::get_called_method_from_trace($backtrace, 2) . '.'; + $level = self::$insideWithNoReplacement ? 4 : 2; + $string .= " Called from " . self::get_called_method_from_trace($backtrace, $level) . '.'; if ($caller) { - user_error($caller . ' is deprecated.' . ($string ? ' ' . $string : ''), E_USER_DEPRECATED); - } else { - user_error($string, E_USER_DEPRECATED); + $string = $caller . ' is deprecated.' . ($string ? ' ' . $string : ''); } + self::$userErrorMessageBuffer[] = [ + 'message' => $string, + 'calledInsideWithNoReplacement' => self::$insideWithNoReplacement + ]; + } + if (!self::$haveSetShutdownFunction && self::isEnabled()) { + // Use a shutdown function rather than immediately calling user_error() so that notices + // do not interfere with setting session varibles i.e. headers already sent error + // it also means the deprecation notices appear below all phpunit output in CI + // which is far nicer than having it spliced between phpunit output + register_shutdown_function(function () { + self::outputNotices(); + }); + self::$haveSetShutdownFunction = true; } } catch (BadMethodCallException $e) { if ($e->getMessage() === InjectorLoader::NO_MANIFESTS_AVAILABLE) { @@ -264,7 +319,7 @@ public static function notice($atVersion, $string = '', $scope = Deprecation::SC throw $e; } } finally { - static::$inside_notice = false; + static::$insideNotice = false; } } diff --git a/src/Dev/FunctionalTest.php b/src/Dev/FunctionalTest.php index c0329c355bb..97025c2915f 100644 --- a/src/Dev/FunctionalTest.php +++ b/src/Dev/FunctionalTest.php @@ -14,6 +14,7 @@ use SilverStripe\Security\SecurityToken; use SilverStripe\View\SSViewer; use SimpleXMLElement; +use SilverStripe\Dev\Deprecation; /* ------------------------------------------------- * @@ -115,7 +116,7 @@ protected function setUp(): void // Disable theme, if necessary if (static::get_disable_themes()) { - SSViewer::config()->update('theme_enabled', false); + SSViewer::config()->set('theme_enabled', false); } // Flush user @@ -123,9 +124,11 @@ protected function setUp(): void // Switch to draft site, if necessary // If you rely on this you should be crafting stage-specific urls instead though. - if (static::get_use_draft_site()) { - $this->useDraftSite(); - } + Deprecation::withNoReplacement(function () { + if (static::get_use_draft_site()) { + $this->useDraftSite(); + } + }); // Unprotect the site, tests are running with the assumption it's off. They will enable it on a case-by-case // basis. @@ -560,7 +563,7 @@ protected function setUp() // Disable theme, if necessary if (static::get_disable_themes()) { - SSViewer::config()->update('theme_enabled', false); + SSViewer::config()->set('theme_enabled', false); } // Flush user @@ -568,9 +571,11 @@ protected function setUp() // Switch to draft site, if necessary // If you rely on this you should be crafting stage-specific urls instead though. - if (static::get_use_draft_site()) { - $this->useDraftSite(); - } + Deprecation::withNoReplacement(function () { + if (static::get_use_draft_site()) { + $this->useDraftSite(); + } + }); // Unprotect the site, tests are running with the assumption it's off. They will enable it on a case-by-case // basis. diff --git a/src/Dev/SapphireTest.php b/src/Dev/SapphireTest.php index d7b08afc984..4440a00c01c 100644 --- a/src/Dev/SapphireTest.php +++ b/src/Dev/SapphireTest.php @@ -329,7 +329,7 @@ protected function setUp(): void } if (class_exists(Cookie::class)) { - Cookie::config()->update('report_errors', false); + Cookie::config()->set('report_errors', false); } if (class_exists(RootURLController::class)) { @@ -347,16 +347,12 @@ protected function setUp(): void if ($this->shouldSetupDatabaseForCurrentTest($fixtureFiles)) { // Assign fixture factory to deprecated prop in case old tests use it over the getter - /** @var FixtureTestState $fixtureState */ - $fixtureState = static::$state->getStateByName('fixtures'); - $this->fixtureFactory = $fixtureState->getFixtureFactory(static::class); - $this->logInWithPermission('ADMIN'); } // turn off template debugging if (class_exists(SSViewer::class)) { - SSViewer::config()->update('source_file_comments', false); + SSViewer::config()->set('source_file_comments', false); } // Set up the test mailer @@ -1206,7 +1202,7 @@ protected function useTestTheme($themeBaseDir, $theme, $callback) if (strpos($themeBaseDir ?? '', BASE_PATH) === 0) { $themeBaseDir = substr($themeBaseDir ?? '', strlen(BASE_PATH)); } - SSViewer::config()->update('theme_enabled', true); + SSViewer::config()->set('theme_enabled', true); SSViewer::set_themes([$themeBaseDir . '/themes/' . $theme, '$default']); try { @@ -1649,7 +1645,7 @@ protected function setUp() } if (class_exists(Cookie::class)) { - Cookie::config()->update('report_errors', false); + Cookie::config()->set('report_errors', false); } if (class_exists(RootURLController::class)) { @@ -1676,7 +1672,7 @@ protected function setUp() // turn off template debugging if (class_exists(SSViewer::class)) { - SSViewer::config()->update('source_file_comments', false); + SSViewer::config()->set('source_file_comments', false); } // Set up the test mailer @@ -2556,7 +2552,7 @@ protected function useTestTheme($themeBaseDir, $theme, $callback) if (strpos($themeBaseDir ?? '', BASE_PATH) === 0) { $themeBaseDir = substr($themeBaseDir ?? '', strlen(BASE_PATH)); } - SSViewer::config()->update('theme_enabled', true); + SSViewer::config()->set('theme_enabled', true); SSViewer::set_themes([$themeBaseDir . '/themes/' . $theme, '$default']); try { diff --git a/src/Dev/Tasks/MigrateFileTask.php b/src/Dev/Tasks/MigrateFileTask.php index 14f2c214b57..797e58ec394 100644 --- a/src/Dev/Tasks/MigrateFileTask.php +++ b/src/Dev/Tasks/MigrateFileTask.php @@ -21,9 +21,12 @@ use SilverStripe\Assets\Dev\Tasks\SecureAssetsMigrationHelper; use SilverStripe\UserForms\Task\RecoverUploadLocationsHelper; use \Bramus\Monolog\Formatter\ColoredLineFormatter; +use SilverStripe\Dev\Deprecation; /** * Migrates all 3.x file dataobjects to use the new DBFile field. + * + * @deprected 4.12.0 Will be removed without equivalent functionality to replace it */ class MigrateFileTask extends BuildTask { @@ -52,6 +55,12 @@ class MigrateFileTask extends BuildTask /** @var Logger */ private $logger; + public function __construct() + { + Deprecation::notice('4.12.0', 'Will be removed without equivalent functionality to replace it', Deprecation::SCOPE_CLASS); + parent::__construct(); + } + public function run($request) { $this->addLogHandlers(); diff --git a/src/Forms/GridField/GridFieldAddExistingAutocompleter.php b/src/Forms/GridField/GridFieldAddExistingAutocompleter.php index d8efa590341..ff6176d9276 100644 --- a/src/Forms/GridField/GridFieldAddExistingAutocompleter.php +++ b/src/Forms/GridField/GridFieldAddExistingAutocompleter.php @@ -262,7 +262,7 @@ public function doSearch($gridField, $request) $json = []; Config::nest(); - SSViewer::config()->update('source_file_comments', false); + SSViewer::config()->set('source_file_comments', false); $viewer = SSViewer::fromString($this->resultsFormat); foreach ($results as $result) { $title = Convert::html2raw($viewer->process($result)); diff --git a/src/Forms/GridField/GridFieldExportButton.php b/src/Forms/GridField/GridFieldExportButton.php index 9e56b76aad2..904219ef29b 100644 --- a/src/Forms/GridField/GridFieldExportButton.php +++ b/src/Forms/GridField/GridFieldExportButton.php @@ -8,6 +8,7 @@ use SilverStripe\Core\Config\Config; use SilverStripe\ORM\DataList; use SilverStripe\ORM\DataObject; +use SilverStripe\ORM\ArrayList; /** * Adds an "Export list" button to the bottom of a {@link GridField}. @@ -221,6 +222,7 @@ public function generateExportFileData($gridField) ? $gridFieldColumnsComponent->getColumnsHandled($gridField) : []; + /** @var ArrayList|DataList $items */ // Remove limit as the list may be paginated, we want the full list for the export $items = $items->limit(null); // Use Generator in applicable cases to reduce memory consumption diff --git a/src/Forms/GridField/GridFieldFilterHeader.php b/src/Forms/GridField/GridFieldFilterHeader.php index 6cd457e4cc8..58599b2fecd 100755 --- a/src/Forms/GridField/GridFieldFilterHeader.php +++ b/src/Forms/GridField/GridFieldFilterHeader.php @@ -102,7 +102,10 @@ public function __construct( callable $updateSearchContext = null, callable $updateSearchForm = null ) { - $this->useLegacyFilterHeader = Config::inst()->get(self::class, 'force_legacy') || $useLegacy; + $forceLegacy = Deprecation::withNoReplacement(function () { + return Config::inst()->get(self::class, 'force_legacy'); + }); + $this->useLegacyFilterHeader = $forceLegacy || $useLegacy; $this->updateSearchContextCallback = $updateSearchContext; $this->updateSearchFormCallback = $updateSearchForm; } @@ -523,7 +526,9 @@ public function getHTMLFragments($gridField) } if ($this->useLegacyFilterHeader) { - $fieldsList = $this->getLegacyFilterHeader($gridField); + $fieldsList = Deprecation::withNoReplacement(function () use ($gridField) { + return $this->getLegacyFilterHeader($gridField); + }); $forTemplate->Fields = $fieldsList; $filterTemplates = SSViewer::get_templates_by_class($this, '_Row', __CLASS__); return ['header' => $forTemplate->renderWith($filterTemplates)]; diff --git a/src/Forms/TreeDropdownField.php b/src/Forms/TreeDropdownField.php index 69201889f03..9ea4048445c 100644 --- a/src/Forms/TreeDropdownField.php +++ b/src/Forms/TreeDropdownField.php @@ -2,7 +2,6 @@ namespace SilverStripe\Forms; -use SilverStripe\Dev\Deprecation; use Exception; use InvalidArgumentException; use SilverStripe\Assets\Folder; @@ -622,13 +621,11 @@ public function getAttributes() /** * HTML-encoded label for this node, including css classes and other markup. * - * @deprecated 4.0.1 Use setTitleField() instead * @param string $field * @return $this */ public function setLabelField($field) { - Deprecation::notice('4.0.1', 'Use setTitleField() instead'); $this->labelField = $field; return $this; } @@ -636,12 +633,10 @@ public function setLabelField($field) /** * HTML-encoded label for this node, including css classes and other markup. * - * @deprecated 4.0.1 Use getTitleField() instead * @return string */ public function getLabelField() { - Deprecation::notice('4.0.1', 'Use getTitleField() instead'); return $this->labelField; } diff --git a/src/Forms/UploadReceiver.php b/src/Forms/UploadReceiver.php index fda6a617de4..9d745b0d456 100644 --- a/src/Forms/UploadReceiver.php +++ b/src/Forms/UploadReceiver.php @@ -6,6 +6,7 @@ use SilverStripe\Assets\File; use SilverStripe\Assets\Upload; use SilverStripe\Assets\Upload_Validator; +use SilverStripe\Core\Convert; /** * Represents a form field which has an Upload() instance and can upload to a folder @@ -47,8 +48,8 @@ protected function constructUploadReceiver() ); // get the lower max size - $maxUpload = File::ini2bytes(ini_get('upload_max_filesize')); - $maxPost = File::ini2bytes(ini_get('post_max_size')); + $maxUpload = Convert::memstring2bytes(ini_get('upload_max_filesize')); + $maxPost = Convert::memstring2bytes(ini_get('post_max_size')); $this->getValidator()->setAllowedMaxFileSize(min($maxUpload, $maxPost)); } diff --git a/src/ORM/ArrayList.php b/src/ORM/ArrayList.php index 74a7cd600ea..83e448b9333 100644 --- a/src/ORM/ArrayList.php +++ b/src/ORM/ArrayList.php @@ -178,18 +178,20 @@ public function toNestedArray() /** * Get a sub-range of this dataobjectset as an array + * Pass null to "remove the limit" - this is for consistency with DataList::limit(null) which itself will + * call SQLSelect::setLimit(null) * - * @param int $length + * @param int|null $length * @param int $offset * @return static */ public function limit($length, $offset = 0) { // Type checking: designed for consistency with DataList::limit() - if (!is_numeric($length) || !is_numeric($offset)) { + if ((!is_numeric($length) || !is_numeric($offset)) && !is_null($length)) { Deprecation::notice( '4.3', - 'Arguments to ArrayList::limit() should be numeric' + 'Arguments to ArrayList::limit() should be numeric or null' ); } diff --git a/src/ORM/Connect/DBSchemaManager.php b/src/ORM/Connect/DBSchemaManager.php index 698f17cd52c..4a893622860 100644 --- a/src/ORM/Connect/DBSchemaManager.php +++ b/src/ORM/Connect/DBSchemaManager.php @@ -2,7 +2,6 @@ namespace SilverStripe\ORM\Connect; -use SilverStripe\Dev\Deprecation; use Exception; use SilverStripe\Control\Director; use SilverStripe\Core\Config\Config; @@ -60,12 +59,9 @@ abstract class DBSchemaManager /** * @param string $table * @param string $class - * - * @deprecated 4.0.1 Will be removed without equivalent functionality */ public static function showTableNameWarning($table, $class) { - Deprecation::notice('4.0.1', 'Will be removed without equivalent functionality'); static::$table_name_warnings[$table] = $class; } diff --git a/src/ORM/Connect/MySQLTransactionManager.php b/src/ORM/Connect/MySQLTransactionManager.php index 452ce334a46..b4d9d1a62cd 100644 --- a/src/ORM/Connect/MySQLTransactionManager.php +++ b/src/ORM/Connect/MySQLTransactionManager.php @@ -20,13 +20,6 @@ public function __construct(Database $dbConn) public function transactionStart($transactionMode = false, $sessionCharacteristics = false) { - if ($transactionMode || $sessionCharacteristics) { - Deprecation::notice( - '4.4', - '$transactionMode and $sessionCharacteristics are deprecated and will be removed in SS5' - ); - } - if ($this->inTransaction) { throw new DatabaseException( "Already in transaction, can't start another. Consider decorating with NestedTransactionManager." diff --git a/src/ORM/DataObject.php b/src/ORM/DataObject.php index aac5f79cb4a..9d92c408612 100644 --- a/src/ORM/DataObject.php +++ b/src/ORM/DataObject.php @@ -2604,11 +2604,6 @@ public function getCMSCompositeValidator(): CompositeValidator // Support for the old method during the deprecation period if ($this->hasMethod('getCMSValidator')) { - Deprecation::notice( - '4.6', - 'getCMSValidator() is removed in 5.0 in favour of getCMSCompositeValidator()' - ); - $compositeValidator->addValidator($this->getCMSValidator()); } diff --git a/src/Security/CMSSecurity.php b/src/Security/CMSSecurity.php index eadd22e1208..1aedbcf69f4 100644 --- a/src/Security/CMSSecurity.php +++ b/src/Security/CMSSecurity.php @@ -187,7 +187,7 @@ public function success() $backURLs = [ $this->getRequest()->requestVar('BackURL'), $this->getRequest()->getSession()->get('BackURL'), - Director::absoluteURL(AdminRootController::config()->get('url_base'), true), + Director::absoluteURL(AdminRootController::config()->get('url_base')), ]; $backURL = null; foreach ($backURLs as $backURL) { diff --git a/src/View/SSViewer.php b/src/View/SSViewer.php index 6dafb12f47c..2057f59747c 100644 --- a/src/View/SSViewer.php +++ b/src/View/SSViewer.php @@ -287,8 +287,11 @@ public static function get_themes() return $themes; } - // Support legacy behaviour - if ($theme = SSViewer::config()->uninherited('theme')) { + // Support @deprecated legacy behaviour + $theme = Deprecation::withNoReplacement(function () { + return SSViewer::config()->uninherited('theme'); + }); + if ($theme) { return [self::PUBLIC_THEME, $theme, self::DEFAULT_THEME]; } diff --git a/src/i18n/i18n.php b/src/i18n/i18n.php index 597a7ececfc..b7357b802a4 100644 --- a/src/i18n/i18n.php +++ b/src/i18n/i18n.php @@ -178,7 +178,6 @@ public static function _t($entity, $arg = null) // inject the variables from injectionArray (if present) $sprintfArgs = []; if ($default && !preg_match('/\{[\w\d]*\}/i', $default ?? '') && preg_match('/%[s,d]/', $default ?? '')) { - Deprecation::notice('5.0', 'sprintf style localisation variables are deprecated'); $sprintfArgs = array_values($injection ?? []); $injection = []; } diff --git a/templates/SilverStripe/Forms/GridField/GridField_Item.ss b/templates/SilverStripe/Forms/GridField/GridField_Item.ss index ed5a5fe156e..c57cd94df2f 100644 --- a/templates/SilverStripe/Forms/GridField/GridField_Item.ss +++ b/templates/SilverStripe/Forms/GridField/GridField_Item.ss @@ -6,7 +6,7 @@