DiskSpaceValidator.php in Automatic Updates 8.2
File
src/Validator/DiskSpaceValidator.php
View source
<?php
namespace Drupal\automatic_updates\Validator;
use Drupal\automatic_updates\AutomaticUpdatesEvents;
use Drupal\automatic_updates\Event\UpdateEvent;
use Drupal\automatic_updates\PathLocator;
use Drupal\automatic_updates\Validation\ValidationResult;
use Drupal\Component\FileSystem\FileSystem;
use Drupal\Component\Utility\Bytes;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\Core\StringTranslation\TranslationInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class DiskSpaceValidator implements EventSubscriberInterface {
use StringTranslationTrait;
protected $pathLocator;
public function __construct(PathLocator $path_locator, TranslationInterface $translation) {
$this->pathLocator = $path_locator;
$this
->setStringTranslation($translation);
}
protected function freeSpace(string $path) : float {
$free_space = disk_free_space($path);
if ($free_space === FALSE) {
throw new \RuntimeException("Cannot get disk information for {$path}.");
}
return $free_space;
}
protected function stat(string $path) : array {
$stat = stat($path);
if ($stat === FALSE) {
throw new \RuntimeException("Cannot get information for {$path}.");
}
return $stat;
}
protected function areSameLogicalDisk(string $root, string $vendor) : bool {
$root_statistics = $this
->stat($root);
$vendor_statistics = $this
->stat($vendor);
return $root_statistics['dev'] === $vendor_statistics['dev'];
}
public function checkDiskSpace(UpdateEvent $event) : void {
$root_path = $this->pathLocator
->getProjectRoot();
$vendor_path = $this->pathLocator
->getVendorDirectory();
$messages = [];
$minimum_mb = 1024;
$minimum_bytes = Bytes::toNumber($minimum_mb . 'M');
if (!$this
->areSameLogicalDisk($root_path, $vendor_path)) {
if ($this
->freeSpace($root_path) < $minimum_bytes) {
$messages[] = $this
->t('Drupal root filesystem "@root" has insufficient space. There must be at least @space megabytes free.', [
'@root' => $root_path,
'@space' => $minimum_mb,
]);
}
if (is_dir($vendor_path) && $this
->freeSpace($vendor_path) < $minimum_bytes) {
$messages[] = $this
->t('Vendor filesystem "@vendor" has insufficient space. There must be at least @space megabytes free.', [
'@vendor' => $vendor_path,
'@space' => $minimum_mb,
]);
}
}
elseif ($this
->freeSpace($root_path) < $minimum_bytes) {
$messages[] = $this
->t('Drupal root filesystem "@root" has insufficient space. There must be at least @space megabytes free.', [
'@root' => $root_path,
'@space' => $minimum_mb,
]);
}
$temp = $this
->temporaryDirectory();
if ($this
->freeSpace($temp) < $minimum_bytes) {
$messages[] = $this
->t('Directory "@temp" has insufficient space. There must be at least @space megabytes free.', [
'@temp' => $temp,
'@space' => $minimum_mb,
]);
}
if ($messages) {
$summary = count($messages) > 1 ? $this
->t("There is not enough disk space to perform an automatic update.") : NULL;
$error = ValidationResult::createError($messages, $summary);
$event
->addValidationResult($error);
}
}
protected function temporaryDirectory() : string {
return FileSystem::getOsTemporaryDirectory();
}
public static function getSubscribedEvents() {
return [
AutomaticUpdatesEvents::READINESS_CHECK => 'checkDiskSpace',
];
}
}