-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathcommerce_product_bundle.install
207 lines (183 loc) · 8.7 KB
/
commerce_product_bundle.install
1
2
3
4
5
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
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
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
127
128
129
130
131
132
133
134
135
136
137
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
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
<?php
/**
* @file
*/
use Drupal\Core\Entity\Sql\SqlContentEntityStorage;
use Drupal\Core\Entity\Sql\SqlContentEntityStorageException;
use Drupal\Core\Session\AccountInterface;
/**
* Implements hook_install().
*/
function commerce_product_bundle_install() {
// Allow all roles to view published product bundles.
user_role_grant_permissions(AccountInterface::ANONYMOUS_ROLE, ['view commerce_product_bundle']);
user_role_grant_permissions(AccountInterface::AUTHENTICATED_ROLE, ['view commerce_product_bundle']);
}
/**
* Update the 'commerce_product_bundle_item_selection' 'selected_qty' column.
*/
function commerce_product_bundle_update_8001() {
$database = \Drupal::database();
$field_tables = [];
$field_tables_processed = 0;
$keys = [
'primary key' => [
'entity_id',
'deleted',
'delta',
'langcode',
],
];
$field_type_manager = \Drupal::service('plugin.manager.field.field_type');
$selection_definition = $field_type_manager->getDefinition('commerce_product_bundle_item_selection');
/** @var \Drupal\commerce_product_bundle\Plugin\Field\FieldType\BundleItemSelection $selection_item_class */
$selection_item_class = $selection_definition['class'];
$column_id = 'selected_qty';
$entity_type_manager = \Drupal::entityTypeManager();
/** @var \Drupal\Core\Entity\EntityFieldManagerInterface $entity_field_manager */
$entity_field_manager = \Drupal::service('entity_field.manager');
$entity_field_map = $entity_field_manager->getFieldMapByFieldType('commerce_product_bundle_item_selection');
// The key-value collection for tracking installed storage schema.
$entity_storage_schema_sql = \Drupal::keyValue('entity.storage_schema.sql');
$entity_definitions_installed = \Drupal::keyValue('entity.definitions.installed');
foreach ($entity_field_map as $entity_type_id => $field_map) {
$entity_storage = $entity_type_manager->getStorage($entity_type_id);
// Only SQL storage based entities are supported / throw known exception.
if (!($entity_storage instanceof SqlContentEntityStorage)) {
continue;
}
$entity_type = $entity_type_manager->getDefinition($entity_type_id);
$field_storage_definitions = $entity_field_manager->getFieldStorageDefinitions($entity_type_id);
/** @var \Drupal\Core\Entity\Sql\DefaultTableMapping $table_mapping */
$table_mapping = $entity_storage->getTableMapping($field_storage_definitions);
/** @var \Drupal\Core\Field\FieldStorageDefinitionInterface $field_storage_definition */
foreach (array_intersect_key($field_storage_definitions, $field_map) as $field_storage_definition) {
$field_name = $field_storage_definition->getName();
try {
$table = $table_mapping->getFieldTableName($field_name);
$selected_qty_field = $table_mapping->getFieldColumnName($field_storage_definition, $column_id);
}
catch (SqlContentEntityStorageException $e) {
continue;
}
// See if the field has a revision table.
$revision_table = NULL;
if ($entity_type->isRevisionable() && $field_storage_definition->isRevisionable()) {
if ($table_mapping->requiresDedicatedTableStorage($field_storage_definition)) {
$revision_table = $table_mapping->getDedicatedRevisionTableName($field_storage_definition);
}
elseif ($table_mapping->allowsSharedTableStorage($field_storage_definition)) {
$revision_table = $entity_type->getRevisionDataTable() ?: $entity_type->getRevisionTable();
}
}
// Load the installed field schema so that it can be updated.
$schema_key = "$entity_type_id.field_schema_data.$field_name";
$field_schema_data = $entity_storage_schema_sql->get($schema_key);
// Update 'selected_qty' field from integer to decimal.
$field_schema = $selection_item_class::schema($field_storage_definition);
$spec = $field_schema['columns'][$column_id];
$db_column = $field_name . '_' . $column_id;
if ($field_schema_data) {
$field_schema_data[$table]['fields'][$selected_qty_field] = $spec;
$field_schema_data[$table]['fields'][$selected_qty_field]['precision'] = '17';
$field_schema_data[$table]['fields'][$selected_qty_field]['scale'] = '2';
if ($revision_table) {
$field_schema_data[$revision_table]['fields'][$selected_qty_field] = $spec;
$field_schema_data[$revision_table]['fields'][$selected_qty_field]['precision'] = '17';
$field_schema_data[$revision_table]['fields'][$selected_qty_field]['scale'] = '2';
}
// Save changes to the installed field schema.
$entity_storage_schema_sql->set($schema_key, $field_schema_data);
if ($table_mapping->allowsSharedTableStorage($field_storage_definition)) {
$key = "$entity_type_id.field_storage_definitions";
if ($definitions = $entity_definitions_installed->get($key)) {
$definitions[$field_name] = $field_storage_definition;
$entity_definitions_installed->set($key, $definitions);
}
}
if ($database->schema()->tableExists($table)) {
$field_tables[$table] = $database->select($table, 't')
->fields('t')
->execute()
->fetchAll();
$database
->truncate($table)
->execute();
db_drop_primary_key($table);
$database
->schema()
->changeField($table, $db_column, $db_column, $field_schema_data[$table]['fields'][$selected_qty_field], $keys);
}
if ($database->schema()->tableExists($revision_table)) {
$field_tables[$revision_table] = $database->select($revision_table, 't')
->fields('t')
->execute()
->fetchAll();
$database
->truncate($revision_table)
->execute();
db_drop_primary_key($revision_table);
$database
->schema()
->changeField($revision_table, $db_column, $db_column, $field_schema_data[$revision_table]['fields'][$selected_qty_field], $keys);
}
}
}
foreach ($field_tables as $table => $rows) {
foreach ($rows as $row) {
$database->insert($table)
->fields((array) $row)
->execute();
}
$field_tables_processed++;
}
return t('@i bundle_item_selection fields were updated.', ['@i' => $field_tables_processed]);
}
}
/**
* Converts 'commerce_product_bundle' and 'commerce_product_bundle_i'
* configurable fields into base fields.
*
* @see https://www.drupal.org/project/commerce_product_bundle/issues/3209648
* Modified from commerce_product_update_8208
*/
function commerce_product_bundle_update_8002(&$sandbox) {
_convert_fields('commerce_product_bundle', 'stores');
_convert_fields('commerce_product_bundle', 'bundle_items');
_convert_fields('commerce_product_bundle_i', 'variations');
}
function _convert_fields($entity_type, $field_name) {
$bundle_info = \Drupal::service('entity_type.bundle.info')
->getBundleInfo($entity_type);
$product_types = array_keys($bundle_info);
$config_factory = \Drupal::configFactory();
$config_manager = \Drupal::service('config.manager');
$entity_type_manager = \Drupal::entityTypeManager();
$entity_field_manager = \Drupal::service('entity_field.manager');
$entity_type_manager->clearCachedDefinitions();
$entity_field_manager->clearCachedFieldDefinitions();
$key = "$entity_type.field_storage_definitions";
$entity_definitions_installed = \Drupal::keyValue('entity.definitions.installed');
$definitions = $entity_definitions_installed->get($key);
/** @var \Drupal\Core\Field\FieldDefinitionInterface[] $base_field_definitions */
$base_field_definitions = $entity_field_manager->getBaseFieldDefinitions($entity_type);
$definitions[$field_name] = $base_field_definitions[$field_name]->getFieldStorageDefinition();
$entity_definitions_installed->set($key, $definitions);
$configuration_to_delete = [];
foreach ($product_types as $bundle) {
$configuration_to_delete[] = "field.field.$entity_type.$bundle.$field_name";
}
$configuration_to_delete[] = "field.storage.$entity_type.$field_name";
$dependents = $config_manager->findConfigEntityDependents('config', $configuration_to_delete);
/** @var \Drupal\Core\Config\Entity\ConfigEntityInterface $config_entity */
foreach ($dependents as $config_name => $config_entity) {
$config_entity = $config_factory->getEditable($config_name);
$dependencies = $config_entity->get('dependencies.config');
$dependencies = array_diff($dependencies, $configuration_to_delete);
$config_entity->set('dependencies.config', array_values($dependencies));
$config_entity->save();
}
foreach ($configuration_to_delete as $config) {
$config_factory->getEditable($config)->delete();
}
}