Newer
Older

Adam G-H
committed
<?php
namespace Drupal\package_manager\EventSubscriber;
use Drupal\Core\Database\Connection;

Adam G-H
committed
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
use Drupal\Core\File\FileSystemInterface;
use Drupal\Core\StreamWrapper\LocalStream;
use Drupal\Core\StreamWrapper\StreamWrapperManagerInterface;
use Drupal\package_manager\Event\PreApplyEvent;
use Drupal\package_manager\Event\PreCreateEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
/**
* Defines an event subscriber to exclude certain paths from staging areas.
*/
class ExcludedPathsSubscriber implements EventSubscriberInterface {
/**
* The Drupal root.
*
* @var string
*/
protected $appRoot;
/**
* The current site path, relative to the Drupal root.
*
* @var string
*/
protected $sitePath;
/**
* The file system service.
*
* @var \Drupal\Core\File\FileSystemInterface
*/
protected $fileSystem;
/**
* The stream wrapper manager service.
*
* @var \Drupal\Core\StreamWrapper\StreamWrapperManagerInterface
*/
protected $streamWrapperManager;
/**
* The database connection.
*
* @var \Drupal\Core\Database\Connection
*/
protected $database;
/**
* Constructs an ExcludedPathsSubscriber.

Adam G-H
committed
*
* @param string $app_root
* The Drupal root.
* @param string $site_path
* The current site path, relative to the Drupal root.
* @param \Drupal\Core\File\FileSystemInterface $file_system
* The file system service.
* @param \Drupal\Core\StreamWrapper\StreamWrapperManagerInterface $stream_wrapper_manager
* The stream wrapper manager service.
* @param \Drupal\Core\Database\Connection $database
* The database connection.

Adam G-H
committed
*/
public function __construct(string $app_root, string $site_path, FileSystemInterface $file_system, StreamWrapperManagerInterface $stream_wrapper_manager, Connection $database) {

Adam G-H
committed
$this->appRoot = $app_root;
$this->sitePath = $site_path;
$this->fileSystem = $file_system;
$this->streamWrapperManager = $stream_wrapper_manager;
$this->database = $database;

Adam G-H
committed
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
}
/**
* Reacts before staged changes are committed the active directory.
*
* @param \Drupal\package_manager\Event\PreApplyEvent $event
* The event object.
*/
public function preApply(PreApplyEvent $event): void {
// Don't copy anything from the staging area's sites/default.
// @todo Make this a lot smarter in https://www.drupal.org/i/3228955.
$event->excludePath('sites/default');
// If the core-vendor-hardening plugin (used in the legacy-project template)
// is present, it may have written a web.config file into the vendor
// directory. We don't want to copy that.
$event->excludePath('web.config');
}
/**
* Excludes paths from a staging area before it is created.
*
* @param \Drupal\package_manager\Event\PreCreateEvent $event
* The event object.
*/
public function preCreate(PreCreateEvent $event): void {
// Automated test site directories should never be staged.
$event->excludePath('sites/simpletest');
// Windows server configuration files, like web.config, should never be
// staged either. (These can be written in the vendor directory by the
// core-vendor-hardening plugin, which is used in the drupal/legacy-project
// template.)
$event->excludePath('web.config');
if ($public = $this->getFilesPath('public')) {
$event->excludePath($public);
}
if ($private = $this->getFilesPath('private')) {
$event->excludePath($private);
}
// Exclude site-specific settings files.
$settings_files = [
'settings.php',
'settings.local.php',
'services.yml',
];
$default_site = 'sites' . DIRECTORY_SEPARATOR . 'default';
foreach ($settings_files as $settings_file) {
$event->excludePath($this->sitePath . DIRECTORY_SEPARATOR . $settings_file);
$event->excludePath($default_site . DIRECTORY_SEPARATOR . $settings_file);
}
// If the database is SQLite, it might be located in the active directory
// and we should not stage it.
if ($this->database->driver() === 'sqlite') {
$options = $this->database->getConnectionOptions();
$database = str_replace($this->appRoot, NULL, $options['database']);
$database = ltrim($database, '/');
$event->excludePath($database);
$event->excludePath("$database-shm");
$event->excludePath("$database-wal");
}

Adam G-H
committed
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
}
/**
* Returns the storage path for a stream wrapper.
*
* This will only work for stream wrappers that extend
* \Drupal\Core\StreamWrapper\LocalStream, which includes the stream wrappers
* for public and private files.
*
* @param string $scheme
* The stream wrapper scheme.
*
* @return string|null
* The storage path for files using the given scheme, relative to the Drupal
* root, or NULL if the stream wrapper does not extend
* \Drupal\Core\StreamWrapper\LocalStream.
*/
private function getFilesPath(string $scheme): ?string {
$wrapper = $this->streamWrapperManager->getViaScheme($scheme);
if ($wrapper instanceof LocalStream) {
return $wrapper->getDirectoryPath();
}
return NULL;
}
/**
* {@inheritdoc}
*/
public static function getSubscribedEvents() {
return [
PreCreateEvent::class => 'preCreate',
PreApplyEvent::class => 'preApply',
];
}
}