Magento 2 Documentation  2.3
Documentation for Magento 2 CMS v2.3 (December 2018)
WhitelistGenerator.php
Go to the documentation of this file.
1 <?php
6 declare(strict_types=1);
7 
9 
22 
27 {
31  private $schemaConfig;
32 
36  private $componentRegistrar;
37 
41  private $jsonPersistor;
42 
46  private $readerComposite;
47 
51  private $primaryDbSchema;
52 
56  private $elementNameResolver;
57 
61  private $deploymentConfig;
62 
71  public function __construct(
72  ComponentRegistrar $componentRegistrar,
73  JsonPersistor $jsonPersistor,
74  SchemaConfig $schemaConfig,
75  ReaderComposite $readerComposite,
76  ElementNameResolver $elementNameResolver,
77  DeploymentConfig $deploymentConfig
78  ) {
79  $this->componentRegistrar = $componentRegistrar;
80  $this->jsonPersistor = $jsonPersistor;
81  $this->schemaConfig = $schemaConfig;
82  $this->readerComposite = $readerComposite;
83  $this->elementNameResolver = $elementNameResolver;
84  $this->deploymentConfig = $deploymentConfig;
85  }
86 
93  public function generate(string $moduleName)
94  {
95  $this->checkMagentoInstallation();
96  $schema = $this->schemaConfig->getDeclarationConfig();
97  if ($moduleName === FileResolverByModule::ALL_MODULES) {
98  foreach (array_keys($this->componentRegistrar->getPaths('module')) as $moduleName) {
99  $this->persistModule($schema, $moduleName);
100  }
101  } else {
102  $this->persistModule($schema, $moduleName);
103  }
104  }
105 
111  private function checkMagentoInstallation()
112  {
113  $tablePrefixLength = $this->deploymentConfig->get(ConfigOptionsListConstants::CONFIG_PATH_DB_PREFIX);
114  if ($tablePrefixLength) {
116  __('Magento was installed with a table prefix. Please re-install without prefix.')
117  );
118  }
119  }
120 
128  private function persistModule(Schema $schema, string $moduleName)
129  {
130  $content = [];
131  $modulePath = $this->componentRegistrar->getPath('module', $moduleName);
132  $whiteListFileName = $modulePath
133  . DIRECTORY_SEPARATOR
135  . DIRECTORY_SEPARATOR
137 
138  //We need to load whitelist file and update it with new revision of code.
139  if (file_exists($whiteListFileName)) {
140  $content = json_decode(file_get_contents($whiteListFileName), true);
141  }
142 
143  $data = $this->filterPrimaryTables($this->readerComposite->read($moduleName));
144  if (!empty($data['table'])) {
145  foreach ($data['table'] as $tableName => $tabledata) {
146  //Do merge between what we have before, and what we have now and filter to only certain attributes.
147  $content = array_replace_recursive(
148  $content,
149  [$tableName => $this->getElementsWithFixedName($tabledata)],
150  [$tableName => $this->getElementsWithAutogeneratedName(
151  $schema,
152  $tableName,
153  $tabledata
154  )]
155  );
156  }
157  if (!empty($content)) {
158  $this->jsonPersistor->persist($content, $whiteListFileName);
159  }
160  }
161  }
162 
169  private function getElementsWithFixedName(array $tableData): array
170  {
171  $declaredStructure = [];
172  if (!empty($tableData['column'])) {
173  $declaredColumns = array_keys($tableData['column']);
174  $declaredStructure['column'] = array_fill_keys($declaredColumns, true);
175  }
176  return $declaredStructure;
177  }
178 
187  private function getElementsWithAutogeneratedName(Schema $schema, string $tableName, array $tableData) : array
188  {
189  $declaredStructure = [];
190  $table = $schema->getTableByName($tableName);
191 
192  $elementType = 'index';
193  if (!empty($tableData[$elementType])) {
194  foreach ($tableData[$elementType] as $tableElementData) {
195  $indexName = $this->elementNameResolver->getFullIndexName(
196  $table,
197  $tableElementData['column'],
198  $tableElementData['indexType'] ?? null
199  );
200  $declaredStructure[$elementType][$indexName] = true;
201  }
202  }
203 
204  $elementType = 'constraint';
205  if (!empty($tableData[$elementType])) {
206  foreach ($tableData[$elementType] as $tableElementData) {
207  if ($tableElementData['type'] === 'foreign') {
208  $referenceTable = $schema->getTableByName($tableElementData['referenceTable']);
209  $constraintName = $this->elementNameResolver->getFullFKName(
210  $table,
211  $table->getColumnByName($tableElementData['column']),
212  $referenceTable,
213  $referenceTable->getColumnByName($tableElementData['referenceColumn'])
214  );
215  } else {
216  $constraintName = $this->elementNameResolver->getFullIndexName(
217  $table,
218  $tableElementData['column'],
219  $tableElementData['type']
220  );
221  }
222  $declaredStructure[$elementType][$constraintName] = true;
223  }
224  }
225 
226  return $declaredStructure;
227  }
228 
234  private function getPrimaryDbSchema(): array
235  {
236  if (!$this->primaryDbSchema) {
237  $this->primaryDbSchema = $this->readerComposite->read('primary');
238  }
239  return $this->primaryDbSchema;
240  }
241 
248  private function filterPrimaryTables(array $moduleDbSchema): array
249  {
250  $primaryDbSchema = $this->getPrimaryDbSchema();
251  if (isset($moduleDbSchema['table']) && isset($primaryDbSchema['table'])) {
252  foreach (array_keys($primaryDbSchema['table']) as $tableNameKey) {
253  unset($moduleDbSchema['table'][$tableNameKey]);
254  }
255  }
256  return $moduleDbSchema;
257  }
258 }
$tableName
Definition: trigger.php:13
$componentRegistrar
Definition: bootstrap.php:23
__()
Definition: __.php:13
__construct(ComponentRegistrar $componentRegistrar, JsonPersistor $jsonPersistor, SchemaConfig $schemaConfig, ReaderComposite $readerComposite, ElementNameResolver $elementNameResolver, DeploymentConfig $deploymentConfig)
$deploymentConfig
$table
Definition: trigger.php:14