DatabaseSanitize.php in Database Sanitize 8
File
src/DatabaseSanitize.php
View source
<?php
namespace Drupal\database_sanitize;
use Drupal\Component\Serialization\Json;
use Drupal\Core\Logger\LoggerChannelFactoryInterface;
use EdisonLabs\MergeYaml\MergeYaml;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\Yaml\Exception\ParseException;
use Symfony\Component\Yaml\Yaml;
class DatabaseSanitize {
const DATABASE_SANITIZE_FILE_NAME = "database.sanitize";
protected $mergeYaml;
protected $logger;
public function __construct(LoggerChannelFactoryInterface $logger) {
$this->logger = $logger
->get('database_sanitize');
$locations = $this
->getSourceLocations();
$output_dir = $this
->getOutputDir();
$this->mergeYaml = new MergeYaml([
self::DATABASE_SANITIZE_FILE_NAME,
], $locations, $output_dir);
}
public static function create(ContainerInterface $container) {
return new static($container
->get('logger.factory'));
}
public function getOutputDir() {
$merge_yaml_config = $this
->getMergeYamlConfig();
if (empty($merge_yaml_config['output-dir'])) {
return '/tmp';
}
return $merge_yaml_config['output-dir'];
}
public function getSourceLocations() {
$merge_yaml_config = $this
->getMergeYamlConfig();
$default_locations = [
DRUPAL_ROOT . '/modules',
DRUPAL_ROOT . '/profiles',
];
$locations = $default_locations;
if (!empty($merge_yaml_config['locations'])) {
$locations = $merge_yaml_config['locations'];
}
$composer_file = DRUPAL_ROOT . '/../composer.json';
$composer_root = dirname($composer_file);
foreach ($locations as &$location) {
if (!file_exists($location)) {
$location = realpath("{$composer_root}/{$location}");
}
}
unset($location);
return $locations;
}
public function getMergeYamlConfig() {
$config =& drupal_static(__FUNCTION__);
if (isset($config)) {
return $config;
}
$composer_file = DRUPAL_ROOT . '/../composer.json';
if (!file_exists($composer_file)) {
return [];
}
$composer_file_content = file_get_contents($composer_file);
$composer_data = Json::decode($composer_file_content);
$config = [];
if (isset($composer_data['extra']['merge-yaml'])) {
$config = $composer_data['extra']['merge-yaml'];
}
return $config;
}
public function getDatabaseSanitizeYmlFileContent() {
$file_content =& drupal_static(__FUNCTION__);
if ($file_content) {
return $file_content;
}
$yml_files = $this->mergeYaml
->getYamlFiles();
if (empty($yml_files)) {
return NULL;
}
$file_content = $this->mergeYaml
->getMergedYmlContent(reset($yml_files));
return $file_content;
}
public function getUnspecifiedTables($yml_file_path = NULL) {
if ($yml_file_path) {
if (!file_exists($yml_file_path)) {
throw new \Exception("File does not exist {$yml_file_path}");
}
$file_content = file_get_contents($yml_file_path);
}
else {
$file_content = $this
->getDatabaseSanitizeYmlFileContent();
}
$db_tables = \Drupal::database()
->query('show tables')
->fetchCol();
if (empty($file_content)) {
return $db_tables;
}
try {
$parsed_file = Yaml::parse($file_content);
} catch (ParseException $exception) {
$message = $exception
->getMessage();
$this->logger
->error("Unable to parse the sanitize YAML file. @message", [
'@message' => $message,
]);
return $db_tables;
}
if (is_null($parsed_file) || !array_key_exists('sanitize', $parsed_file)) {
$this->logger
->error("The 'sanitize' key is not defined");
return $db_tables;
}
if (empty($parsed_file['sanitize'])) {
return $db_tables;
}
$yml_tables = [];
foreach ($parsed_file['sanitize'] as $machine_name => $tables) {
foreach ($tables as $table_name => $definition) {
if (is_array($definition) && !empty(array_filter($definition)) && !array_key_exists('description', $definition)) {
$this->logger
->warning('Table \'@table_name\' defined by \'@machine_name\' does not specify a \'description\' key', [
'@table_name' => $table_name,
'@machine_name' => $machine_name,
]);
continue;
}
if (is_array($definition) && !empty(array_filter($definition)) && !array_key_exists('query', $definition)) {
$this->logger
->warning('Table \'@table_name\' defined by \'@machine_name\' does not specify a \'query\' key', [
'@table_name' => $table_name,
'@machine_name' => $machine_name,
]);
continue;
}
if (in_array($table_name, $yml_tables)) {
continue;
}
if (substr($table_name, -1) == '*') {
$table_pattern = substr($table_name, 0, -1);
foreach ($db_tables as $db_table) {
if (substr($db_table, 0, strlen($table_pattern)) === $table_pattern) {
array_push($yml_tables, $db_table);
}
}
continue;
}
array_push($yml_tables, $table_name);
}
}
$missing = array_diff($db_tables, $yml_tables);
if (is_array($missing) && empty($missing)) {
$this->logger
->info('All database tables are already specified in sanitize YML files');
return [];
}
sort($missing);
return $missing;
}
}