123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144 |
- <?php
- namespace Drupal\reinstall\EventSubscriber;
- use Drupal\Component\Utility\Unicode;
- use Drupal\Core\File\FileSystem;
- use Drupal\Core\File\FileSystemInterface;
- use Drupal\file\Entity\File;
- use Drupal\reinstall\DumperEvent;
- use Drupal\reinstall\ReinstallEvents;
- use Symfony\Component\EventDispatcher\EventSubscriberInterface;
- /**
- * Class FilePostDump performs physical file copy on file dump.
- */
- class FilePostDump implements EventSubscriberInterface {
- /**
- * The file_system service.
- *
- * @var \Drupal\Core\File\FileSystemInterface
- */
- protected $fileSystem;
- /**
- * The export/import path.
- *
- * @var string
- */
- protected $importPath;
- /**
- * FilePostDump constructor.
- *
- * @param \Drupal\Core\File\FileSystemInterface $fileSystem
- * The file_system service.
- * @param string $importPath
- * The reinstall.path parameter.
- */
- public function __construct(FileSystemInterface $fileSystem, string $importPath) {
- $this->fileSystem = $fileSystem;
- $this->importPath = $importPath;
- }
- /**
- * {@inheritdoc}
- */
- public static function getSubscribedEvents() {
- return [
- ReinstallEvents::POST_DUMP => 'onDumpPost',
- ];
- }
- /**
- * Callback for POST_DUMP event.
- *
- * @param \Drupal\reinstall\DumperEvent $event
- * The post-dump event.
- */
- public function onDumpPost(DumperEvent $event) {
- if ($event->storage->getEntityTypeId() !== 'file') {
- return;
- }
- $this->dumpFiles($event->bundleName, $event->entities);
- }
- /**
- * Dump the actual files for a file entity bundle.
- *
- * @param string $bundleName
- * The bundle name.
- * @param array $files
- * The file URLs.
- */
- public function dumpFiles(string $bundleName, array $files) {
- $importPath = $this->importPath;
- $dir = "$importPath/$bundleName";
- $usedNamespaces = array_keys(array_reduce($files, [__CLASS__, 'namespacesReducer'], []));
- $lists = [];
- foreach ($usedNamespaces as $ns) {
- // XXX Consider using \0 to support xargs: file names MAY contain spaces.
- $path = "$dir/$ns.list.txt";
- $nsDir = "$dir/$ns";
- if (!is_dir($nsDir)) {
- echo "Creating $nsDir\n";
- mkdir($nsDir, 0777, TRUE);
- }
- // fopen() is in text mode by default.
- $lists[$ns] = [
- 'dir' => $nsDir,
- 'handle' => fopen($path, 'w'),
- ];
- }
- /** @var \Drupal\file\Entity\File $file */
- foreach ($files as $file) {
- $uri = $file->getFileUri();
- $target = file_uri_target($uri);
- $ns = $this->fileSystem->uriScheme($uri);
- fwrite($lists[$ns]['handle'], $target . "\n");
- $dest = $lists[$ns]['dir'] . '/' . $target;
- $dir = dirname($dest);
- if (!is_dir($dir)) {
- mkdir($dir, 0777, TRUE);
- }
- file_unmanaged_copy($uri, $dest, FILE_EXISTS_REPLACE);
- }
- foreach ($lists as $list) {
- fclose($list['handle']);
- }
- }
- /**
- * An array_reduce() callback to collect namespaces from file entities.
- *
- * @param string[] $accu
- * The namespaces accumulator.
- * @param \Drupal\file\Entity\File $fileItem
- * A file description.
- *
- * @return string[]
- * An array of namespaces used on the site.
- *
- * @see \Drupal\reinstall\Dumper::dumpFiles()
- */
- protected static function namespacesReducer(array $accu, File $fileItem) {
- $uri = $fileItem->getFileUri();
- // Plain filenames without a namespace. Should not happen, but...
- if (FALSE === ($len = Unicode::strpos($uri, '://'))) {
- return $accu;
- };
- $namespace = Unicode::substr($uri, 0, $len);
- $accu[$namespace] = TRUE;
- return $accu;
- }
- }
|