3v4l.org

run code in 500+ PHP versions simultaneously
<?php $config = [ 'finishing' => [ 'attributes' => [ '167' => [ 'option' => '5020', 'values' => [ '5818' => '41004', ], ], '176' => [ 'option' => '5021', 'values' => [ '5774' => '41014', ], ], ], 'pattern' => [ 'attribute' => '177', 'new_attribute' => '295', ], 'left' => [ 'bundle' => '16712', 'bundle_options' => [ '335' => '335', ], 'grinded' => [ 'old_product' => '16649', 'patterns' => [ '5780' => [ 'product' => '45938', 'value' => '7289', 'selection' => '7279', ], ], ], ], 'right' => [ 'bundle' => '16713', 'bundle_options' => [ '339' => '339', ], 'grinded' => [ 'old_product' => '16649', 'patterns' => [ '5780' => [ 'product' => '45938', 'value' => '7289', 'selection' => '7303', ], ], ], ], ], ]; function migrate(array $request, array $config): array { $config = $config['finishing']; foreach (['left', 'right'] as $sideName) { $request = migrateSide( $request, $config, $config[$sideName] ); } return $request; } function migrateSide( array $request, array $config, array $side ): array { $bundleOptions = $request['bundle_option'] ?? []; $superAttributes = $request['super_attribute'] ?? []; foreach ($side['bundle_options'] as $oldOption => $newOption) { if (!isset($bundleOptions[$oldOption])) { continue; } $oldSelection = (string) $bundleOptions[$oldOption]; /* * Find super attributes belonging to this bundle option. * * Example: * * 16712-335-16649-176 => 5774 * ^^^ ^^^^^ * opt product */ $source = findSourceAttributes( $superAttributes, $oldOption, $oldSelection ); /* * No matching super attributes means this is not * a Grinded configuration. */ if ($source === null) { continue; } /* * Check whether the selected product is the old * Grinded product. */ if ( $source['selection_product'] !== $side['grinded']['old_product'] ) { continue; } $request = migrateGrinded( $request, $config, $side, $oldOption, $newOption, $source ); } return $request; } function findSourceAttributes( array $superAttributes, string $oldOption, string $oldSelection ): ?array { $result = [ 'bundle_product' => null, 'selection_product' => null, 'attributes' => [], 'keys' => [], ]; foreach ($superAttributes as $key => $value) { $parts = explode('-', (string) $key); /* * Ignore unrelated keys. * * A super_attribute key that contains "-" * but is malformed is considered an error only * if it looks like one of our bundle keys. */ if (count($parts) !== 4) { continue; } [ $bundleProduct, $option, $selectionProduct, $attributeId ] = $parts; if ($option !== $oldOption) { continue; } /* * We need the old selected product ID from the key. */ if ($result['selection_product'] === null) { $result['selection_product'] = $selectionProduct; } elseif ( $result['selection_product'] !== $selectionProduct ) { throw new RuntimeException( "Different selection products found for bundle option {$oldOption}" ); } if ($result['bundle_product'] === null) { $result['bundle_product'] = $bundleProduct; } elseif ( $result['bundle_product'] !== $bundleProduct ) { throw new RuntimeException( "Different bundle products found for bundle option {$oldOption}" ); } $result['attributes'][$attributeId] = (string) $value; $result['keys'][] = $key; } if ($result['selection_product'] === null) { return null; } return $result; } function migrateGrinded( array $request, array $config, array $side, string $oldOption, string $newOption, array $source ): array { $attributes = $source['attributes']; /* * --------------------------------------------------------- * 1. Get old groundsole pattern * --------------------------------------------------------- */ $patternAttribute = $config['pattern']['attribute']; if (!isset($attributes[$patternAttribute])) { throw new RuntimeException( "Missing pattern attribute {$patternAttribute} " . "for bundle option {$oldOption}" ); } $oldPattern = $attributes[$patternAttribute]; if (!isset($side['grinded']['patterns'][$oldPattern])) { throw new RuntimeException( "Unknown pattern {$oldPattern} " . "for bundle option {$oldOption}" ); } $pattern = $side['grinded']['patterns'][$oldPattern]; /* * --------------------------------------------------------- * 2. Validate all attributes that become custom options * --------------------------------------------------------- */ foreach ($config['attributes'] as $attributeId => $mapping) { if (!isset($attributes[$attributeId])) { throw new RuntimeException( "Missing attribute {$attributeId} " . "for bundle option {$oldOption}" ); } $oldValue = $attributes[$attributeId]; if (!isset($mapping['values'][$oldValue])) { throw new RuntimeException( "Unknown value {$oldValue} " . "for attribute {$attributeId}" ); } } /* * --------------------------------------------------------- * 3. Change bundle selection * --------------------------------------------------------- */ $request['bundle_option'][$newOption] = $pattern['selection']; if ($oldOption !== $newOption) { unset($request['bundle_option'][$oldOption]); } /* * --------------------------------------------------------- * 4. Remove old super attributes * --------------------------------------------------------- */ foreach ($source['keys'] as $key) { unset($request['super_attribute'][$key]); } /* * --------------------------------------------------------- * 5. Add new pattern_variant super attribute * * Example: * * 16712-335-45938-295 => 7289 * --------------------------------------------------------- */ $newSuperAttributeKey = sprintf( '%s-%s-%s-%s', $source['bundle_product'], $newOption, $pattern['product'], $config['pattern']['new_attribute'] ); $request['super_attribute'][$newSuperAttributeKey] = $pattern['value']; /* * --------------------------------------------------------- * 6. Convert old configurable attributes into * custom options * * Example: * * 16712_335_options: * { * "5020": "41004", * "5021": "41014" * } * --------------------------------------------------------- */ $customOptionKey = sprintf( '%s_%s_options', $source['bundle_product'], $newOption ); $options = $request[$customOptionKey] ?? []; foreach ($config['attributes'] as $attributeId => $mapping) { $oldValue = $attributes[$attributeId]; $options[$mapping['option']] = $mapping['values'][$oldValue]; } $request[$customOptionKey] = $options; return $request; } /* * ============================================================= * INPUT * ============================================================= * * Paste your initial JSON here. */ $inputJson = <<<'JSON' { "product": "16714", "selected_configurable_option": "", "related_product": "", "item": "16714", "form_key": "a5TW22FK2IX7OSib", "files": [], "milling_files": "1088", "images": { "left": { "product_id": "", "path": "" }, "right": { "product_id": "", "path": "" } }, "next_step": "", "back_step": "", "back_from_checkout": "", "grouped_bundle": [ "16712", "16713" ], "step_selected_bundle": [ "16712", "16713" ], "bundle_option": { "333": "5549", "334": "4148", "335": "4151", "337": "5550", "338": "4162", "339": "4165" }, "super_attribute": { "16712-333-18898-163": "5652", "16712-333-18898-162": "5917", "16712-334-16680-160": "5642", "16712-335-16649-176": "5774", "16712-335-16649-177": "5780", "16712-335-16649-167": "5818", "16713-337-18898-163": "5652", "16713-337-18898-162": "5917", "16713-338-16680-160": "5642", "16713-339-16649-176": "5774", "16713-339-16649-177": "5780", "16713-339-16649-167": "5818" }, "16712_333_options": { "2914": "", "2915": "29596" }, "16712_334_options": { "2910": "" }, "16712_335_options": { "2906": "" }, "16712_options": { "1403": "" }, "16713_337_options": { "2914": "", "2915": "29596" }, "16713_338_options": { "2910": "" }, "16713_339_options": { "2906": "" }, "16713_options": { "1404": "" } } JSON; /* * ============================================================= * RUN * ============================================================= */ try { $input = json_decode( $inputJson, true, 512, JSON_THROW_ON_ERROR ); $output = migrate($input, $config); echo json_encode( $output, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES ); } catch (Throwable $e) { echo json_encode( [ 'error' => $e->getMessage(), ], JSON_PRETTY_PRINT ); }
Output for 8.2.0 - 8.2.34, 8.3.0 - 8.3.35, 8.4.1 - 8.4.26, 8.5.0 - 8.5.11
{ "product": "16714", "selected_configurable_option": "", "related_product": "", "item": "16714", "form_key": "a5TW22FK2IX7OSib", "files": [], "milling_files": "1088", "images": { "left": { "product_id": "", "path": "" }, "right": { "product_id": "", "path": "" } }, "next_step": "", "back_step": "", "back_from_checkout": "", "grouped_bundle": [ "16712", "16713" ], "step_selected_bundle": [ "16712", "16713" ], "bundle_option": { "333": "5549", "334": "4148", "335": "7279", "337": "5550", "338": "4162", "339": "7303" }, "super_attribute": { "16712-333-18898-163": "5652", "16712-333-18898-162": "5917", "16712-334-16680-160": "5642", "16713-337-18898-163": "5652", "16713-337-18898-162": "5917", "16713-338-16680-160": "5642", "16712-335-45938-295": "7289", "16713-339-45938-295": "7289" }, "16712_333_options": { "2914": "", "2915": "29596" }, "16712_334_options": { "2910": "" }, "16712_335_options": { "2906": "", "5020": "41004", "5021": "41014" }, "16712_options": { "1403": "" }, "16713_337_options": { "2914": "", "2915": "29596" }, "16713_338_options": { "2910": "" }, "16713_339_options": { "2906": "", "5020": "41004", "5021": "41014" }, "16713_options": { "1404": "" } }

preferences:
29.69 ms | 1142 KiB | 7 Q