mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-02 14:18:46 +02:00
Merge branch '4' into 5.0
This commit is contained in:
commit
f6d8d27c89
@ -6,12 +6,15 @@ use SilverStripe\Control\Middleware\HTTPMiddlewareAware;
|
|||||||
use SilverStripe\Core\Application;
|
use SilverStripe\Core\Application;
|
||||||
use SilverStripe\Core\Environment;
|
use SilverStripe\Core\Environment;
|
||||||
use SilverStripe\Core\Kernel;
|
use SilverStripe\Core\Kernel;
|
||||||
|
use SilverStripe\Core\Manifest\Module;
|
||||||
use SilverStripe\Core\Startup\FlushDiscoverer;
|
use SilverStripe\Core\Startup\FlushDiscoverer;
|
||||||
use SilverStripe\Core\Startup\CompositeFlushDiscoverer;
|
use SilverStripe\Core\Startup\CompositeFlushDiscoverer;
|
||||||
use SilverStripe\Core\Startup\CallbackFlushDiscoverer;
|
use SilverStripe\Core\Startup\CallbackFlushDiscoverer;
|
||||||
use SilverStripe\Core\Startup\RequestFlushDiscoverer;
|
use SilverStripe\Core\Startup\RequestFlushDiscoverer;
|
||||||
use SilverStripe\Core\Startup\ScheduledFlushDiscoverer;
|
use SilverStripe\Core\Startup\ScheduledFlushDiscoverer;
|
||||||
use SilverStripe\Core\Startup\DeployFlushDiscoverer;
|
use SilverStripe\Core\Startup\DeployFlushDiscoverer;
|
||||||
|
use SilverStripe\Dev\Deprecation;
|
||||||
|
use SilverStripe\GraphQL\TypeCreator;
|
||||||
|
|
||||||
class HTTPApplication implements Application
|
class HTTPApplication implements Application
|
||||||
{
|
{
|
||||||
@ -130,6 +133,10 @@ class HTTPApplication implements Application
|
|||||||
return $this->callMiddleware($request, function ($request) use ($callback, $flush) {
|
return $this->callMiddleware($request, function ($request) use ($callback, $flush) {
|
||||||
// Pre-request boot
|
// Pre-request boot
|
||||||
$this->getKernel()->boot($flush);
|
$this->getKernel()->boot($flush);
|
||||||
|
|
||||||
|
// This is the earliest point we can do this and guarantee it's hit exactly once per request.
|
||||||
|
$this->warnAboutDeprecatedSetups();
|
||||||
|
|
||||||
return call_user_func($callback, $request);
|
return call_user_func($callback, $request);
|
||||||
});
|
});
|
||||||
} catch (HTTPResponse_Exception $ex) {
|
} catch (HTTPResponse_Exception $ex) {
|
||||||
@ -138,4 +145,48 @@ class HTTPApplication implements Application
|
|||||||
$this->getKernel()->shutdown();
|
$this->getKernel()->shutdown();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Trigger deprecation notices for legacy configuration which is deprecated but
|
||||||
|
* doesn't have deprecation notices directly on the relevant API
|
||||||
|
*
|
||||||
|
* Don't remove this method even if it's just a no-op - we'll reuse this mechanism
|
||||||
|
* in the future as needed.
|
||||||
|
*/
|
||||||
|
private function warnAboutDeprecatedSetups()
|
||||||
|
{
|
||||||
|
// TypeCreator is a class unique to GraphQL v3 - we use it in other areas to detect
|
||||||
|
// which version is being used.
|
||||||
|
if (class_exists(TypeCreator::class)) {
|
||||||
|
Deprecation::notice(
|
||||||
|
'4.13.0',
|
||||||
|
'silverstripe/graphql 3.x is deprecated. Upgrade to 4.x instead.'
|
||||||
|
. ' See https://docs.silverstripe.org/en/4/upgrading/upgrading_to_graphql_4/',
|
||||||
|
Deprecation::SCOPE_GLOBAL
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// The alternate_public_dir config property is deprecated, but because it's
|
||||||
|
// always fetched it'll throw a deprecation warning whether you've set it or not.
|
||||||
|
// There are also multiple mechanisms which can result in this bad configuration.
|
||||||
|
if (PUBLIC_DIR !== 'public' || Director::publicDir() !== PUBLIC_DIR) {
|
||||||
|
Deprecation::notice(
|
||||||
|
'4.13.0',
|
||||||
|
'Use of a public webroot other than "public" is deprecated.'
|
||||||
|
. ' See https://docs.silverstripe.org/en/4/changelogs/4.1.0#public-folder/',
|
||||||
|
Deprecation::SCOPE_GLOBAL
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// This change of defaults has no other deprecation notice being emitted currently.
|
||||||
|
$project = new Module(BASE_PATH, BASE_PATH);
|
||||||
|
if ($project->getResourcesDir() === '') {
|
||||||
|
Deprecation::notice(
|
||||||
|
'4.13.0',
|
||||||
|
'The RESOURCES_DIR constant will change to "_resources" by default.'
|
||||||
|
. ' See https://docs.silverstripe.org/en/5/changelogs/5.0.0/#api-general',
|
||||||
|
Deprecation::SCOPE_GLOBAL
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -289,14 +289,14 @@ class ClassInfo
|
|||||||
*/
|
*/
|
||||||
public static function classes_for_file($filePath)
|
public static function classes_for_file($filePath)
|
||||||
{
|
{
|
||||||
$absFilePath = Director::getAbsFile($filePath);
|
$absFilePath = Convert::slashes(Director::getAbsFile($filePath));
|
||||||
$classManifest = ClassLoader::inst()->getManifest();
|
$classManifest = ClassLoader::inst()->getManifest();
|
||||||
$classes = $classManifest->getClasses();
|
$classes = $classManifest->getClasses();
|
||||||
$classNames = $classManifest->getClassNames();
|
$classNames = $classManifest->getClassNames();
|
||||||
|
|
||||||
$matchedClasses = [];
|
$matchedClasses = [];
|
||||||
foreach ($classes as $lowerClass => $compareFilePath) {
|
foreach ($classes as $lowerClass => $compareFilePath) {
|
||||||
if (strcasecmp($absFilePath ?? '', $compareFilePath ?? '') === 0) {
|
if (strcasecmp($absFilePath, Convert::slashes($compareFilePath ?? '')) === 0) {
|
||||||
$matchedClasses[$lowerClass] = $classNames[$lowerClass];
|
$matchedClasses[$lowerClass] = $classNames[$lowerClass];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -312,14 +312,14 @@ class ClassInfo
|
|||||||
*/
|
*/
|
||||||
public static function classes_for_folder($folderPath)
|
public static function classes_for_folder($folderPath)
|
||||||
{
|
{
|
||||||
$absFolderPath = Director::getAbsFile($folderPath);
|
$absFolderPath = Convert::slashes(Director::getAbsFile($folderPath));
|
||||||
$classManifest = ClassLoader::inst()->getManifest();
|
$classManifest = ClassLoader::inst()->getManifest();
|
||||||
$classes = $classManifest->getClasses();
|
$classes = $classManifest->getClasses();
|
||||||
$classNames = $classManifest->getClassNames();
|
$classNames = $classManifest->getClassNames();
|
||||||
|
|
||||||
$matchedClasses = [];
|
$matchedClasses = [];
|
||||||
foreach ($classes as $lowerClass => $compareFilePath) {
|
foreach ($classes as $lowerClass => $compareFilePath) {
|
||||||
if (stripos($compareFilePath ?? '', $absFolderPath ?? '') === 0) {
|
if (stripos(Convert::slashes($compareFilePath ?? ''), $absFolderPath) === 0) {
|
||||||
$matchedClasses[$lowerClass] = $classNames[$lowerClass];
|
$matchedClasses[$lowerClass] = $classNames[$lowerClass];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -227,6 +227,7 @@ trait CustomMethods
|
|||||||
*
|
*
|
||||||
* @param object $object
|
* @param object $object
|
||||||
* @return array
|
* @return array
|
||||||
|
* @deprecated 4.13.0 Will be replaced by findMethodsFrom() in CMS 5
|
||||||
*/
|
*/
|
||||||
protected function findMethodsFrom($object)
|
protected function findMethodsFrom($object)
|
||||||
{
|
{
|
||||||
|
@ -10,19 +10,13 @@ use SilverStripe\Core\Injector\InjectorLoader;
|
|||||||
use SilverStripe\Core\Manifest\Module;
|
use SilverStripe\Core\Manifest\Module;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles raising an notice when accessing a deprecated method
|
* Handles raising an notice when accessing a deprecated method, class, configuration, or behaviour.
|
||||||
*
|
*
|
||||||
* A pattern used in SilverStripe when deprecating a method is to add something like
|
* Sometimes we want to mark that a method will be deprecated in some future version and shouldn't be used in
|
||||||
* user_error('This method is deprecated', E_USER_NOTICE);
|
|
||||||
* to the method
|
|
||||||
*
|
|
||||||
* However sometimes we want to mark that a method will be deprecated in some future version and shouldn't be used in
|
|
||||||
* new code, but not forbid in the current version - for instance when that method is still heavily used in framework
|
* new code, but not forbid in the current version - for instance when that method is still heavily used in framework
|
||||||
* or cms.
|
* or cms.
|
||||||
*
|
*
|
||||||
* This class abstracts the above pattern and adds a way to do that.
|
* See https://docs.silverstripe.org/en/contributing/release_process/#deprecation
|
||||||
*
|
|
||||||
* Each call to notice passes a version that the notice will be valid from.
|
|
||||||
*/
|
*/
|
||||||
class Deprecation
|
class Deprecation
|
||||||
{
|
{
|
||||||
@ -114,6 +108,12 @@ class Deprecation
|
|||||||
$level = 1;
|
$level = 1;
|
||||||
}
|
}
|
||||||
$newLevel = $level;
|
$newLevel = $level;
|
||||||
|
// handle closures inside withNoReplacement()
|
||||||
|
if (self::$insideWithNoReplacement
|
||||||
|
&& substr($backtrace[$newLevel]['function'], -strlen('{closure}')) === '{closure}'
|
||||||
|
) {
|
||||||
|
$newLevel = $newLevel + 2;
|
||||||
|
}
|
||||||
// handle call_user_func
|
// handle call_user_func
|
||||||
if ($level === 4 && strpos($backtrace[2]['function'] ?? '', 'call_user_func') !== false) {
|
if ($level === 4 && strpos($backtrace[2]['function'] ?? '', 'call_user_func') !== false) {
|
||||||
$newLevel = 5;
|
$newLevel = 5;
|
||||||
@ -190,10 +190,10 @@ class Deprecation
|
|||||||
// Do not add to self::$userErrorMessageBuffer, as the backtrace is too expensive
|
// Do not add to self::$userErrorMessageBuffer, as the backtrace is too expensive
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Getting a backtrace is slow, so we only do it if we need it
|
// Getting a backtrace is slow, so we only do it if we need it
|
||||||
$backtrace = null;
|
$backtrace = null;
|
||||||
|
|
||||||
// Get the calling scope
|
// Get the calling scope
|
||||||
if ($scope == Deprecation::SCOPE_METHOD) {
|
if ($scope == Deprecation::SCOPE_METHOD) {
|
||||||
$backtrace = debug_backtrace(0);
|
$backtrace = debug_backtrace(0);
|
||||||
@ -204,7 +204,7 @@ class Deprecation
|
|||||||
} else {
|
} else {
|
||||||
$caller = false;
|
$caller = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (substr($string, -1) != '.') {
|
if (substr($string, -1) != '.') {
|
||||||
$string .= ".";
|
$string .= ".";
|
||||||
}
|
}
|
||||||
|
@ -394,14 +394,7 @@ class StandardRelatedDataService implements RelatedDataService
|
|||||||
*/
|
*/
|
||||||
private function prepareClassNameLiteral(string $value): string
|
private function prepareClassNameLiteral(string $value): string
|
||||||
{
|
{
|
||||||
$c = chr(92);
|
return DB::get_conn()->quoteString($value);
|
||||||
$escaped = str_replace($c ?? '', "{$c}{$c}", $value ?? '');
|
|
||||||
// postgres
|
|
||||||
if (stripos(get_class(DB::get_conn()), 'postgres') !== false) {
|
|
||||||
return "E'{$escaped}'";
|
|
||||||
}
|
|
||||||
// mysql
|
|
||||||
return "'{$escaped}'";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -24,6 +24,7 @@ class Sources implements Resettable
|
|||||||
*
|
*
|
||||||
* @config
|
* @config
|
||||||
* @var array
|
* @var array
|
||||||
|
* @deprecated 4.0.0 Use SilverStripe\Core\Manifest\ModuleManifest.module_priority instead
|
||||||
*/
|
*/
|
||||||
private static $module_priority = [];
|
private static $module_priority = [];
|
||||||
|
|
||||||
@ -35,7 +36,6 @@ class Sources implements Resettable
|
|||||||
public function getSortedModules()
|
public function getSortedModules()
|
||||||
{
|
{
|
||||||
$sortedModules = [];
|
$sortedModules = [];
|
||||||
|
|
||||||
foreach (ModuleLoader::inst()->getManifest()->getModules() as $module) {
|
foreach (ModuleLoader::inst()->getManifest()->getModules() as $module) {
|
||||||
$sortedModules[$module->getName()] = $module->getPath();
|
$sortedModules[$module->getName()] = $module->getPath();
|
||||||
};
|
};
|
||||||
|
@ -457,7 +457,7 @@ class i18nTextCollector
|
|||||||
$this->getWriter()->write(
|
$this->getWriter()->write(
|
||||||
$entities,
|
$entities,
|
||||||
$this->defaultLocale,
|
$this->defaultLocale,
|
||||||
$this->baseSavePath . '/' . $module->getRelativePath()
|
$this->baseSavePath . DIRECTORY_SEPARATOR . $module->getRelativePath()
|
||||||
);
|
);
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
@ -511,25 +511,25 @@ class i18nTextCollector
|
|||||||
$modulePath = $module->getPath();
|
$modulePath = $module->getPath();
|
||||||
|
|
||||||
// Search all .ss files in themes
|
// Search all .ss files in themes
|
||||||
if (stripos($module->getRelativePath() ?? '', 'themes/') === 0) {
|
if (stripos($module->getRelativePath() ?? '', 'themes' . DIRECTORY_SEPARATOR) === 0) {
|
||||||
return $this->getFilesRecursive($modulePath, null, 'ss');
|
return $this->getFilesRecursive($modulePath, null, 'ss');
|
||||||
}
|
}
|
||||||
|
|
||||||
// If non-standard module structure, search all root files
|
// If non-standard module structure, search all root files
|
||||||
if (!is_dir("{$modulePath}/code") && !is_dir("{$modulePath}/src")) {
|
if (!is_dir($modulePath . DIRECTORY_SEPARATOR . 'code') && !is_dir($modulePath . DIRECTORY_SEPARATOR . 'src')) {
|
||||||
return $this->getFilesRecursive($modulePath);
|
return $this->getFilesRecursive($modulePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get code files
|
// Get code files
|
||||||
if (is_dir("{$modulePath}/src")) {
|
if (is_dir($modulePath . DIRECTORY_SEPARATOR . 'src')) {
|
||||||
$files = $this->getFilesRecursive("{$modulePath}/src", null, 'php');
|
$files = $this->getFilesRecursive($modulePath . DIRECTORY_SEPARATOR . 'src', null, 'php');
|
||||||
} else {
|
} else {
|
||||||
$files = $this->getFilesRecursive("{$modulePath}/code", null, 'php');
|
$files = $this->getFilesRecursive($modulePath . DIRECTORY_SEPARATOR . 'code', null, 'php');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Search for templates in this module
|
// Search for templates in this module
|
||||||
if (is_dir("{$modulePath}/templates")) {
|
if (is_dir($modulePath . DIRECTORY_SEPARATOR . 'templates')) {
|
||||||
$templateFiles = $this->getFilesRecursive("{$modulePath}/templates", null, 'ss');
|
$templateFiles = $this->getFilesRecursive($modulePath . DIRECTORY_SEPARATOR . 'templates', null, 'ss');
|
||||||
} else {
|
} else {
|
||||||
$templateFiles = $this->getFilesRecursive($modulePath, null, 'ss');
|
$templateFiles = $this->getFilesRecursive($modulePath, null, 'ss');
|
||||||
}
|
}
|
||||||
@ -957,7 +957,7 @@ class i18nTextCollector
|
|||||||
$fileList = [];
|
$fileList = [];
|
||||||
}
|
}
|
||||||
// Skip ignored folders
|
// Skip ignored folders
|
||||||
if (is_file("{$folder}/_manifest_exclude") || preg_match($folderExclude ?? '', $folder ?? '')) {
|
if (is_file($folder . DIRECTORY_SEPARATOR . '_manifest_exclude') || preg_match($folderExclude ?? '', $folder ?? '')) {
|
||||||
return $fileList;
|
return $fileList;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -151,6 +151,22 @@ class DeprecationTest extends SapphireTest
|
|||||||
Deprecation::outputNotices();
|
Deprecation::outputNotices();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testNoticeWithNoReplacementTrue()
|
||||||
|
{
|
||||||
|
$message = implode(' ', [
|
||||||
|
'SilverStripe\Dev\Tests\DeprecationTest->testNoticeWithNoReplacementTrue is deprecated.',
|
||||||
|
'My message.',
|
||||||
|
'Called from PHPUnit\Framework\TestCase->runTest.'
|
||||||
|
]);
|
||||||
|
$this->expectDeprecation();
|
||||||
|
$this->expectDeprecationMessage($message);
|
||||||
|
Deprecation::enable(true);
|
||||||
|
Deprecation::withNoReplacement(function () {
|
||||||
|
Deprecation::notice('123', 'My message.');
|
||||||
|
});
|
||||||
|
Deprecation::outputNotices();
|
||||||
|
}
|
||||||
|
|
||||||
public function testClassWithNoReplacement()
|
public function testClassWithNoReplacement()
|
||||||
{
|
{
|
||||||
$message = implode(' ', [
|
$message = implode(' ', [
|
||||||
|
Loading…
Reference in New Issue
Block a user