Merge branch '4.4' into 4

This commit is contained in:
Aaron Carlino 2019-06-10 16:37:16 +12:00
commit e2da7b0dc4
5 changed files with 114 additions and 38 deletions

View File

@ -22,6 +22,7 @@
"sake"
],
"require": {
"bramus/monolog-colored-line-formatter": "~2.0",
"composer/installers": "~1.0",
"embed/embed": "^3.0",
"league/csv": "^8",

View File

@ -56,8 +56,12 @@ class DefaultCacheFactory implements CacheFactory
$directory = isset($args['directory']) ? $args['directory'] : null;
$version = isset($args['version']) ? $args['version'] : null;
// In-memory caches are typically more resource constrained (number of items and storage space).
// Give cache consumers an opt-out if they are expecting to create large caches with long lifetimes.
$useInMemoryCache = isset($args['useInMemoryCache']) ? $args['useInMemoryCache'] : true;
// Check support
$apcuSupported = $this->isAPCUSupported();
$apcuSupported = ($this->isAPCUSupported() && $useInMemoryCache);
$phpFilesSupported = $this->isPHPFilesSupported();
// If apcu isn't supported, phpfiles is the next best preference
@ -72,8 +76,11 @@ class DefaultCacheFactory implements CacheFactory
}
// Chain this cache with ApcuCache
// Note that the cache lifetime will be shorter there by default, to ensure there's enough
// resources for "hot cache" items in APCu as a resource constrained in memory cache.
$apcuNamespace = $namespace . ($namespace ? '_' : '') . md5(BASE_PATH);
$apcu = $this->createCache(ApcuCache::class, [$apcuNamespace, (int) $defaultLifetime / 5, $version]);
return $this->createCache(ChainCache::class, [[$apcu, $fs]]);
}

View File

@ -2,6 +2,7 @@
namespace SilverStripe\Dev\Tasks;
use Monolog\Handler\FilterHandler;
use Monolog\Handler\StreamHandler;
use Monolog\Logger;
use Psr\Log\LoggerInterface;
@ -11,10 +12,12 @@ use SilverStripe\Assets\Dev\Tasks\FileMigrationHelper;
use SilverStripe\Assets\Storage\AssetStore;
use SilverStripe\Assets\Storage\FileHashingService;
use SilverStripe\Control\Director;
use SilverStripe\Core\Environment;
use SilverStripe\Core\Injector\Injector;
use SilverStripe\Logging\PreformattedEchoHandler;
use SilverStripe\Dev\BuildTask;
use SilverStripe\Assets\Dev\Tasks\SecureAssetsMigrationHelper;
use \Bramus\Monolog\Formatter\ColoredLineFormatter;
/**
* Migrates all 3.x file dataobjects to use the new DBFile field.
@ -49,8 +52,18 @@ class MigrateFileTask extends BuildTask
Injector::inst()->get(FileHashingService::class)->enableCache();
// Set max time and memory limit
Environment::increaseTimeLimitTo();
Environment::setMemoryLimitMax(-1);
Environment::increaseMemoryLimitTo(-1);
$this->extend('preFileMigration');
$this->logger->warn(
'Please read https://docs.silverstripe.org/en/4/developer_guides/files/file_migration/ ' .
'before running this task.'
);
$subtasks = !empty($args['only']) ? explode(',', $args['only']) : $this->defaultSubtasks;
$subtask = 'move-files';
@ -59,15 +72,23 @@ class MigrateFileTask extends BuildTask
$this->logger->error("No file migration helper detected");
} else {
$this->extend('preFileMigrationSubtask', $subtask);
$this->logger->info("### Migrating filesystem and database records ({$subtask})");
$this->logger->info('If the task fails or times out, run it again and it will start where it left off.');
$migrated = FileMigrationHelper::singleton()->run();
if ($migrated) {
$this->logger->info("{$migrated} File DataObjects upgraded");
} else {
$this->logger->info("No File DataObjects need upgrading");
}
$this->logger->notice("######################################################");
$this->logger->notice("Migrating filesystem and database records ({$subtask})");
$this->logger->notice("######################################################");
FileMigrationHelper::singleton()
->setLogger($this->logger)
->run();
// TODO Split file migration helper into two tasks,
// and report back on their process counts consistently here
// if ($count) {
// $this->logger->info("{$count} File objects upgraded");
// } else {
// $this->logger->info("No File objects needed upgrading");
// }
$this->extend('postFileMigrationSubtask', $subtask);
}
}
@ -78,16 +99,19 @@ class MigrateFileTask extends BuildTask
$this->logger->error("LegacyThumbnailMigrationHelper not found");
} else {
$this->extend('preFileMigrationSubtask', $subtask);
$this->logger->info("### Migrating existing thumbnails ({$subtask})");
$moved = LegacyThumbnailMigrationHelper::singleton()
$this->logger->notice("#############################################################");
$this->logger->notice("Migrating existing thumbnails to new file format ({$subtask})");
$this->logger->notice("#############################################################");
$paths = LegacyThumbnailMigrationHelper::singleton()
->setLogger($this->logger)
->run($this->getStore());
if ($moved) {
$this->logger->info(sprintf("%d thumbnails moved", count($moved)));
if ($paths) {
$this->logger->info(sprintf("%d thumbnails moved", count($paths)));
} else {
$this->logger->info("No thumbnails moved");
$this->logger->info("No thumbnails needed to be moved");
}
$this->extend('postFileMigrationSubtask', $subtask);
@ -100,8 +124,21 @@ class MigrateFileTask extends BuildTask
$this->logger->error("ImageThumbnailHelper not found");
} else {
$this->extend('preFileMigrationSubtask', $subtask);
$this->logger->info("### Generating new CMS UI thumbnails ({$subtask})");
ImageThumbnailHelper::singleton()->run();
$this->logger->notice("#############################################");
$this->logger->notice("Generating new CMS UI thumbnails ({$subtask})");
$this->logger->notice("#############################################");
$count = ImageThumbnailHelper::singleton()
->setLogger($this->logger)
->run();
if ($count > 0) {
$this->logger->info("Created {$count} CMS UI thumbnails");
} else {
$this->logger->info("No CMS UI thumbnails needed to be created");
}
$this->extend('postFileMigrationSubtask', $subtask);
}
}
@ -113,11 +150,17 @@ class MigrateFileTask extends BuildTask
} else {
$this->extend('preFileMigrationSubtask', $subtask);
$this->logger->info("### Fixing folder permissions ({$subtask})");
$updated = FixFolderPermissionsHelper::singleton()->run();
$this->logger->notice("####################################################");
$this->logger->notice("Fixing secure-assets folder permissions ({$subtask})");
$this->logger->notice("####################################################");
$this->logger->debug('Only required if the 3.x project included silverstripe/secure-assets');
if ($updated > 0) {
$this->logger->info("Repaired {$updated} folders with broken CanViewType settings");
$count = FixFolderPermissionsHelper::singleton()
->setLogger($this->logger)
->run();
if ($count > 0) {
$this->logger->info("Repaired {$count} folders with broken CanViewType settings");
} else {
$this->logger->info("No folders required fixes");
}
@ -133,11 +176,21 @@ class MigrateFileTask extends BuildTask
} else {
$this->extend('preFileMigrationSubtask', $subtask);
$this->logger->info("### Fixing secure-assets ({$subtask})");
$moved = SecureAssetsMigrationHelper::singleton()
$this->logger->notice("#####################################################");
$this->logger->notice("Fixing secure-assets folder restrictions ({$subtask})");
$this->logger->notice("#####################################################");
$this->logger->debug('Only required if the 3.x project included silverstripe/secure-assets');
$paths = SecureAssetsMigrationHelper::singleton()
->setLogger($this->logger)
->run($this->getStore());
if (count($paths) > 0) {
$this->logger->info(sprintf("Repaired %d folders broken folder restrictions", count($paths)));
} else {
$this->logger->info("No folders required fixes");
}
$this->extend('postFileMigrationSubtask', $subtask);
}
}
@ -151,9 +204,8 @@ class MigrateFileTask extends BuildTask
{
return <<<TXT
Imports all files referenced by File dataobjects into the new Asset Persistence Layer introduced in 4.0.
Moves existing thumbnails, and generates new thumbnail sizes for the CMS UI.
Fixes file permissions.
If the task fails or times out, run it again and it will start where it left off.
Moves existing thumbnails, and generates new thumbnail sizes for the CMS UI. Fixes file permissions.
If the task fails or times out, run it again and if possible the tasks will start where they left off.
You need to flush your cache after running this task via CLI.
See https://docs.silverstripe.org/en/4/developer_guides/files/file_migration/.
TXT;
@ -198,13 +250,29 @@ TXT;
*/
protected function addLogHandlers()
{
if ($logger = Injector::inst()->get(LoggerInterface::class)) {
if (Director::is_cli()) {
$logger->pushHandler(new StreamHandler('php://stdout'));
$logger->pushHandler(new StreamHandler('php://stderr', Logger::WARNING));
} else {
$logger->pushHandler(new PreformattedEchoHandler());
}
}
// Using a global service here so other systems can control and redirect log output,
// for example when this task is run as part of a queuedjob
$logger = Injector::inst()->get(LoggerInterface::class)->withName('log');
$formatter = new ColoredLineFormatter();
$formatter->ignoreEmptyContextAndExtra();
$errorHandler = new StreamHandler('php://stderr', Logger::ERROR);
$errorHandler->setFormatter($formatter);
$standardHandler = new StreamHandler('php://stdout');
$standardHandler->setFormatter($formatter);
// Avoid double logging of errors
$standardFilterHandler = new FilterHandler(
$standardHandler,
Logger::DEBUG,
Logger::WARNING
);
$logger->pushHandler($standardFilterHandler);
$logger->pushHandler($errorHandler);
$this->logger = $logger;
}
}

View File

@ -323,7 +323,7 @@ class GridFieldDetailForm_ItemRequest extends RequestHandler
$rightGroup->push($previousAndNextGroup);
if ($component && $component->getShowAdd()) {
if ($component && $component->getShowAdd() && $this->record->canCreate()) {
$rightGroup->push(
LiteralField::create(
'new-record',

View File

@ -18,13 +18,13 @@ class MonologErrorHandler implements ErrorHandler
* Set the PSR-3 logger to send errors & exceptions to. Will overwrite any previously configured
* loggers
*
* @deprecated 4.4.0:5.0.0 Use pushHandler() instead
* @deprecated 4.4.0:5.0.0 Use pushLogger() instead
* @param LoggerInterface $logger
* @return $this
*/
public function setLogger(LoggerInterface $logger)
{
Deprecation::notice('4.4.0', 'Please use pushHandler() instead');
Deprecation::notice('4.4.0', 'Please use pushLogger() instead');
$this->loggers = [$logger];
return $this;
@ -33,12 +33,12 @@ class MonologErrorHandler implements ErrorHandler
/**
* Get the first registered PSR-3 logger to send errors & exceptions to
*
* @deprecated 4.4.0:5.0.0 Use getHandlers() instead
* @deprecated 4.4.0:5.0.0 Use getLoggers() instead
* @return LoggerInterface
*/
public function getLogger()
{
Deprecation::notice('4.4.0', 'Please use getHandlers() instead');
Deprecation::notice('4.4.0', 'Please use getLoggers() instead');
return reset($this->loggers);
}