Skip to content
Snippets Groups Projects

Issue #3363938: Package Manager should ignore default.settings.php and default.services.yml

Merged Issue #3363938: Package Manager should ignore default.settings.php and default.services.yml
1 unresolved thread
1 unresolved thread
@@ -69,11 +69,26 @@ class SiteConfigurationExcluder implements EventSubscriberInterface {
/**
* Makes the staged `sites/default` directory world-writable.
*
* This is done to allow the core scaffold plugin to make changes in
* `sites/default`, if necessary, without breaking if `sites/default` is not
* writable (this can happen because rsync perserves directory permissions,
* and Drupal will try to harden the site directory's permissions as much as
* possible). We specifically exclude the `default.settings.php` and
* `default.services.yml` files from Package Manager operations, so we want to
* allow the scaffold plugin to make whatever changes it wants to those files
* in the stage directory.
*
* @param \Drupal\package_manager\Event\PostCreateEvent $event
* The event being handled.
*
* @see ::excludeSiteConfiguration()
*/
public function makeDefaultSiteDirectoryWritable(PostCreateEvent $event): void {
$dir = $this->getDefaultSiteDirectoryPath($event->stage->getStageDirectory());
// If the directory doesn't even exist, there's nothing to do here.
if (!is_dir($dir)) {
return;
}
if (!$this->fileSystem->chmod($dir, 0777)) {
throw new FileException("Could not change permissions on '$dir'.");
}
@@ -86,25 +101,48 @@ class SiteConfigurationExcluder implements EventSubscriberInterface {
* The event being handled.
*
* @throws \Drupal\Core\File\Exception\FileException
* If the permissions of the live `sites/default` cannot be determined, or
* changed on the staged `sites/default`.
* If the permissions of either the live or staged `sites/default` cannot
* be determined, or cannot be changed on the staged `sites/default`.
*/
public function syncDefaultSiteDirectoryPermissions(PreApplyEvent $event): void {
$live_dir = $this->getDefaultSiteDirectoryPath($this->pathLocator->getProjectRoot());
$staged_dir = $this->getDefaultSiteDirectoryPath($event->stage->getStageDirectory());
$original_permissions = fileperms($live_dir);
if ($original_permissions === FALSE) {
throw new FileException("Could not determine permissions for '$live_dir'.");
// If the directory doesn't even exist, there's nothing to do here.
if (!is_dir($staged_dir)) {
return;
}
$live_dir = $this->getDefaultSiteDirectoryPath($this->pathLocator->getProjectRoot());
// @see \Symfony\Component\Filesystem\Filesystem::copy() for another use
// of the 0111 bitmask.
if (!$this->fileSystem->chmod($staged_dir, $original_permissions & 0111)) {
// This is borrowed from \Symfony\Component\Filesystem\Filesystem::copy(),
// to ensure the correct permissions are preserved (chmod() requires
// permissions to be sent as an octal number, but fileperms() returns a
// decimal number, because PHP is just great).
$permissions = $this->getPermissions($staged_dir) | ($this->getPermissions($live_dir) & 0111);
if (!$this->fileSystem->chmod($staged_dir, $permissions)) {
throw new FileException("Could not change permissions on '$staged_dir'.");
}
}
/**
* Gets the current file permissions of a path.
*
* @param string $path
* The path to examine.
*
* @return int
* The current permissions of the path.
*
* @throws \Drupal\Core\File\Exception\FileException
* Thrown if the file permissions cannot be determined.
*/
private function getPermissions(string $path): int {
$permissions = fileperms($path);
if ($permissions === FALSE) {
throw new FileException("Could not determine permissions for '$path'.");
}
return $permissions;
}
/**
* Returns the full path to `sites/default`, relative to a root directory.
*
@@ -115,12 +153,12 @@ class SiteConfigurationExcluder implements EventSubscriberInterface {
* The full path to `sites/default` within the given root directory.
*/
private function getDefaultSiteDirectoryPath(string $root_dir): string {
$dir = [$root_dir, 'sites', 'default'];
$dir = [$root_dir];
$web_root = $this->pathLocator->getWebRoot();
if ($web_root) {
array_splice($dir, 1, 0, $web_root);
$dir[] = $web_root;
}
return implode(DIRECTORY_SEPARATOR, $dir);
return implode(DIRECTORY_SEPARATOR, [...$dir, 'sites', 'default']);
}
/**
Loading