Unverified Commit c392f9a1 authored by Dave Reid's avatar Dave Reid Committed by Dave Reid
Browse files

Issue #2987939 by Dave Reid, rbayliss: Fixed edge case scenario where...

Issue #2987939 by Dave Reid, rbayliss: Fixed edge case scenario where xmlsitemap_clear_directory() may accidentally delete the file system. This only happens if the module configuration is removed or deleted before the module is uninstalled.
parent 4bcbba22
......@@ -3,6 +3,7 @@
namespace Drupal\xmlsitemap;
use Drupal\Component\Uuid\UuidInterface;
use Drupal\Core\Cache\MemoryCache\MemoryCacheInterface;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Config\Entity\ConfigEntityStorage;
use Drupal\Core\Entity\EntityInterface;
......@@ -36,10 +37,11 @@ class XmlSitemapStorage extends ConfigEntityStorage {
* The language manager.
* @param \Drupal\Core\State\StateInterface $state
* The state service.
* @param \Drupal\Core\Cache\MemoryCache\MemoryCacheInterface|null $memory_cache
* The memory cache backend.
*/
public function __construct(EntityTypeInterface $entity_type, ConfigFactoryInterface $config_factory, UuidInterface $uuid_service, LanguageManagerInterface $language_manager, StateInterface $state) {
parent::__construct($entity_type, $config_factory, $uuid_service, $language_manager);
public function __construct(EntityTypeInterface $entity_type, ConfigFactoryInterface $config_factory, UuidInterface $uuid_service, LanguageManagerInterface $language_manager, StateInterface $state, MemoryCacheInterface $memory_cache = NULL) {
parent::__construct($entity_type, $config_factory, $uuid_service, $language_manager, $memory_cache);
$this->state = $state;
}
......@@ -52,7 +54,8 @@ class XmlSitemapStorage extends ConfigEntityStorage {
$container->get('config.factory'),
$container->get('uuid'),
$container->get('language_manager'),
$container->get('state')
$container->get('state'),
$container->has('entity.memory_cache') ? $container->get('entity.memory_cache') : NULL
);
}
......
<?php
namespace Drupal\Tests\xmlsitemap\Kernel;
/**
* Tests directory functions.
*
* @group xmlsitemap
*/
class DirectoryTest extends KernelTestBase {
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
}
/**
* Test xmlsitemap_clear_directory().
*
* @covers ::xmlsitemap_get_directory
* @covers ::xmlsitemap_clear_directory
* @covers ::_xmlsitemap_delete_recursive
*/
public function testClearDirectory() {
// Set up a couple more directories and files.
$directory = 'public://not-xmlsitemap';
file_prepare_directory($directory, FILE_CREATE_DIRECTORY | FILE_MODIFY_PERMISSIONS);
$directory = 'public://xmlsitemap/test';
file_prepare_directory($directory, FILE_CREATE_DIRECTORY | FILE_MODIFY_PERMISSIONS);
file_unmanaged_save_data('File unrelated to XML sitemap', 'public://not-xmlsitemap/file.txt');
file_unmanaged_save_data('File unrelated to XML sitemap', 'public://file.txt');
file_unmanaged_save_data('Test contents', 'public://xmlsitemap/test/index.xml');
// Set the directory to an empty value.
\Drupal::configFactory()->getEditable('xmlsitemap.settings')->clear('path')->save();
drupal_static_reset('xmlsitemap_get_directory');
$result = xmlsitemap_clear_directory(NULL, TRUE);
// Test that nothing was deleted.
$this->assertFileExists('public://xmlsitemap/test/index.xml');
$this->assertDirectoryExists('public://not-xmlsitemap');
$this->assertFileExists('public://file.txt');
$this->assertFalse($result);
// Reset the value back to the default.
\Drupal::configFactory()->getEditable('xmlsitemap.settings')->set('path', 'xmlsitemap')->save();
drupal_static_reset('xmlsitemap_get_directory');
$result = xmlsitemap_clear_directory(NULL, TRUE);
// Test that only the xmlsitemap directory was deleted..xml');
$this->assertDirectoryNotExists('public://xmlsitemap/test');
$this->assertDirectoryExists('public://not-xmlsitemap');
$this->assertFileExists('public://file.txt');
$this->assertTrue($result);
}
}
<?php
namespace Drupal\Tests\xmlsitemap\Kernel;
use Drupal\KernelTests\KernelTestBase as CoreKernelTestBase;
/**
* Base class for xmlsitemap kernel tests.
*/
abstract class KernelTestBase extends CoreKernelTestBase {
/**
* {@inheritdoc}
*/
public static $modules = [
'system',
'xmlsitemap',
];
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
$this->installConfig(['xmlsitemap']);
$this->installSchema('xmlsitemap', ['xmlsitemap']);
// Install hooks are not run with kernel tests.
xmlsitemap_install();
$this->assertDirectoryExists('public://xmlsitemap');
}
/**
* {@inheritdoc}
*
* This method is only available in PHPUnit 6+.
*/
public static function assertDirectoryExists($directory, $message = '') {
if (method_exists(get_parent_class(), 'assertDirectoryExists')) {
parent::assertDirectoryExists($directory, $message);
}
else {
parent::assertTrue(is_dir($directory), $message);
}
}
/**
* {@inheritdoc}
*
* This method is only available in PHPUnit 6+.
*/
public static function assertDirectoryNotExists($directory, $message = '') {
if (method_exists(get_parent_class(), 'assertDirectoryNotExists')) {
parent::assertDirectoryNotExists($directory, $message);
}
else {
parent::assertFalse(is_dir($directory), $message);
}
}
}
......@@ -318,13 +318,6 @@ function xmlsitemap_install() {
* Implements hook_uninstall().
*/
function xmlsitemap_uninstall() {
// Remove config variables.
$variables = array_keys(xmlsitemap_config_variables());
$editable = \Drupal::configFactory()->getEditable('xmlsitemap.settings');
foreach ($variables as $variable) {
$editable->clear($variable);
}
$variables = array_keys(xmlsitemap_state_variables());
foreach ($variables as $variable) {
\Drupal::state()->delete($variable);
......
......@@ -477,7 +477,10 @@ function xmlsitemap_get_directory(XmlSitemapInterface $sitemap = NULL) {
$directory = \Drupal::config('xmlsitemap.settings')->get('path');
}
if ($sitemap != NULL && !empty($sitemap->id)) {
if (empty($directory)) {
return FALSE;
}
elseif ($sitemap != NULL && !empty($sitemap->id)) {
return file_build_uri($directory . '/' . $sitemap->id);
}
else {
......@@ -534,8 +537,12 @@ function xmlsitemap_check_all_directories() {
* Returns TRUE is operation was successful, FALSE otherwise.
*/
function xmlsitemap_clear_directory(XmlSitemapInterface $sitemap = NULL, $delete = FALSE) {
$directory = xmlsitemap_get_directory($sitemap);
return _xmlsitemap_delete_recursive($directory, $delete);
if ($directory = xmlsitemap_get_directory($sitemap)) {
return _xmlsitemap_delete_recursive($directory, $delete);
}
else {
return FALSE;
}
}
/**
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment