FileStorage.php in Drupal 9
File
core/lib/Drupal/Core/Config/FileStorage.php
View source
<?php
namespace Drupal\Core\Config;
use Drupal\Component\FileCache\FileCacheFactory;
use Drupal\Component\FileSecurity\FileSecurity;
use Drupal\Component\Serialization\Exception\InvalidDataTypeException;
use Drupal\Core\File\FileSystemInterface;
use Drupal\Core\Serialization\Yaml;
class FileStorage implements StorageInterface {
protected $collection;
protected $directory = '';
protected $fileCache;
public function __construct($directory, $collection = StorageInterface::DEFAULT_COLLECTION) {
$this->directory = $directory;
$this->collection = $collection;
$this->fileCache = FileCacheFactory::get('config', [
'cache_backend_class' => NULL,
]);
}
public function getFilePath($name) {
return $this
->getCollectionDirectory() . '/' . $name . '.' . static::getFileExtension();
}
public static function getFileExtension() {
return 'yml';
}
protected function ensureStorage() {
$dir = $this
->getCollectionDirectory();
$success = $this
->getFileSystem()
->prepareDirectory($dir, FileSystemInterface::CREATE_DIRECTORY | FileSystemInterface::MODIFY_PERMISSIONS);
if ($dir == $this->directory) {
$success = $success && FileSecurity::writeHtaccess($this->directory);
}
if (!$success) {
throw new StorageException('Failed to create config directory ' . $dir);
}
return $this;
}
public function exists($name) {
return file_exists($this
->getFilePath($name));
}
public function read($name) {
if (!$this
->exists($name)) {
return FALSE;
}
$filepath = $this
->getFilePath($name);
if ($data = $this->fileCache
->get($filepath)) {
return $data;
}
$data = file_get_contents($filepath);
try {
$data = $this
->decode($data);
} catch (InvalidDataTypeException $e) {
throw new UnsupportedDataTypeConfigException('Invalid data type in config ' . $name . ', found in file ' . $filepath . ': ' . $e
->getMessage());
}
$this->fileCache
->set($filepath, $data);
return $data;
}
public function readMultiple(array $names) {
$list = [];
foreach ($names as $name) {
if ($data = $this
->read($name)) {
$list[$name] = $data;
}
}
return $list;
}
public function write($name, array $data) {
try {
$encoded_data = $this
->encode($data);
} catch (InvalidDataTypeException $e) {
throw new StorageException("Invalid data type in config {$name}: {$e->getMessage()}");
}
$target = $this
->getFilePath($name);
$status = @file_put_contents($target, $encoded_data);
if ($status === FALSE) {
$this
->ensureStorage();
$status = @file_put_contents($target, $encoded_data);
}
if ($status === FALSE) {
throw new StorageException('Failed to write configuration file: ' . $this
->getFilePath($name));
}
else {
$this
->getFileSystem()
->chmod($target);
}
$this->fileCache
->set($target, $data);
return TRUE;
}
public function delete($name) {
if (!$this
->exists($name)) {
return FALSE;
}
$this->fileCache
->delete($this
->getFilePath($name));
return $this
->getFileSystem()
->unlink($this
->getFilePath($name));
}
public function rename($name, $new_name) {
$status = @rename($this
->getFilePath($name), $this
->getFilePath($new_name));
if ($status === FALSE) {
return FALSE;
}
$this->fileCache
->delete($this
->getFilePath($name));
$this->fileCache
->delete($this
->getFilePath($new_name));
return TRUE;
}
public function encode($data) {
return Yaml::encode($data);
}
public function decode($raw) {
$data = Yaml::decode($raw);
if (!is_array($data)) {
return FALSE;
}
return $data;
}
public function listAll($prefix = '') {
$dir = $this
->getCollectionDirectory();
if (!is_dir($dir)) {
return [];
}
$extension = '.' . static::getFileExtension();
$files = scandir($dir);
$names = [];
$pattern = '/^' . preg_quote($prefix, '/') . '.*' . preg_quote($extension, '/') . '$/';
foreach ($files as $file) {
if ($file[0] !== '.' && preg_match($pattern, $file)) {
$names[] = basename($file, $extension);
}
}
return $names;
}
public function deleteAll($prefix = '') {
$files = $this
->listAll($prefix);
$success = !empty($files);
foreach ($files as $name) {
if (!$this
->delete($name) && $success) {
$success = FALSE;
}
}
if ($success && $this->collection != StorageInterface::DEFAULT_COLLECTION) {
if (!(new \FilesystemIterator($this
->getCollectionDirectory()))
->valid()) {
$this
->getFileSystem()
->rmdir($this
->getCollectionDirectory());
}
}
return $success;
}
public function createCollection($collection) {
return new static($this->directory, $collection);
}
public function getCollectionName() {
return $this->collection;
}
public function getAllCollectionNames() {
if (!is_dir($this->directory)) {
return [];
}
$collections = $this
->getAllCollectionNamesHelper($this->directory);
sort($collections);
return $collections;
}
protected function getAllCollectionNamesHelper($directory) {
$collections = [];
$pattern = '/\\.' . preg_quote($this
->getFileExtension(), '/') . '$/';
foreach (new \DirectoryIterator($directory) as $fileinfo) {
if ($fileinfo
->isDir() && !$fileinfo
->isDot()) {
$collection = $fileinfo
->getFilename();
$sub_collections = $this
->getAllCollectionNamesHelper($directory . '/' . $collection);
if (!empty($sub_collections)) {
foreach ($sub_collections as $sub_collection) {
$collections[] = $collection . '.' . $sub_collection;
}
}
foreach (scandir($directory . '/' . $collection) as $file) {
if ($file[0] !== '.' && preg_match($pattern, $file)) {
$collections[] = $collection;
break;
}
}
}
}
return $collections;
}
protected function getCollectionDirectory() {
if ($this->collection == StorageInterface::DEFAULT_COLLECTION) {
$dir = $this->directory;
}
else {
$dir = $this->directory . '/' . str_replace('.', '/', $this->collection);
}
return $dir;
}
private function getFileSystem() {
return \Drupal::service('file_system');
}
}