Skip to content

Instantly share code, notes, and snippets.

@tayyebi
Last active December 30, 2024 12:49
Show Gist options
  • Save tayyebi/d9eb04d7db474acb36ae484239c05906 to your computer and use it in GitHub Desktop.
Save tayyebi/d9eb04d7db474acb36ae484239c05906 to your computer and use it in GitHub Desktop.
Transforms JSON data by moving values between specified addresses within the JSON structure (destructive transformation).
<?php
/**
* JSON Transformer (Destructive)
*
* Copyright (c) 2025 Microsoft Copilot
* Copyright (c) 2025 Gemini (Google)
* Copyright (c) 2025 MohammadReza Tayyebi
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
error_reporting(E_ALL);
ini_set('display_errors', 1);
if (isset($_POST['apply_transformations'])) {
$source_json = $_POST['source_json'];
$transformations = isset($_POST['transformations']) ? $_POST['transformations'] : [];
setcookie('source_json', $source_json, time() + 86400);
$_COOKIE['source_json'] = $source_json;
setcookie('transformations', json_encode($transformations), time() + 86400);
$_COOKIE['transformations'] = json_encode($transformations);
$source_data = json_decode($source_json, true);
if (json_last_error() !== JSON_ERROR_NONE) {
$error_message = 'Invalid JSON format: ' . json_last_error_msg();
} else {
$output_data = &$source_data;
foreach ($transformations as $transformation) {
$source = $transformation['source'];
$destination = $transformation['destination'];
$operation = $transformation['operation'];
$value = getValueByAddress($output_data, $source);
if ($value !== null) {
setValueByAddress($output_data, $source, $destination, $operation);
} else if (!empty($source)){
$error_message .= "Could not find value at source address: $source<br>";
}
}
$output_json = json_encode($output_data, JSON_PRETTY_PRINT);
}
}
$transformations = isset($_COOKIE['transformations']) ? json_decode($_COOKIE['transformations'], true) : [];
$source_json = isset($_COOKIE['source_json']) ? $_COOKIE['source_json'] : '';
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>JSON Transformer</title>
<style>
.column {
float: left;
width: 30%;
padding: 10px;
box-sizing: border-box;
}
.row:after {
content: "";
display: table;
clear: both;
}
#transformations .transformation {
margin-bottom: 5px;
}
</style>
</head>
<body>
<h1>JSON Transformer</h1>
<form method="post">
<div class="row">
<div class="column">
<h2>Source JSON</h2>
<textarea name="source_json" rows="10" cols="30"><?php echo $source_json ?></textarea>
</div>
<div class="column">
<h2>Transformations</h2>
<div id="transformations">
<?php
if (!empty($transformations)) {
foreach ($transformations as $index => $transformation) {
echo '<div class="transformation">';
echo '<select name="transformations[' . $index . '][operation]">';
echo '<option value="move" ' . ($transformation['operation'] == 'move' ? 'selected' : '') . '>Move</option>';
echo '<option value="copy" ' . ($transformation['operation'] == 'copy' ? 'selected' : '') . '>Copy</option>';
echo '<option value="remove" ' . ($transformation['operation'] == 'remove' ? 'selected' : '') . '>Remove</option>';
echo '</select>';
echo '<input type="text" name="transformations[' . $index . '][source]" value="' . htmlspecialchars($transformation['source']) . '" placeholder="Source Address">';
echo '<input type="text" name="transformations[' . $index . '][destination]" value="' . htmlspecialchars($transformation['destination']) . '" placeholder="Destination Address">';
echo '</div>';
}
}
?>
</div>
<button type="button" onclick="addTransformation()">Add Transformation</button>
</div>
<script>
function addTransformation() {
var index = document.querySelectorAll('.transformation').length;
var container = document.getElementById('transformations');
var div = document.createElement('div');
div.classList.add('transformation');
div.innerHTML = '<select name="transformations[' + index + '][operation]"><option value="move">Move</option><option value="copy">Copy</option><option value="remove">Remove</option></select>';
div.innerHTML += '<input type="text" name="transformations[' + index + '][source]" placeholder="Source Address">';
div.innerHTML += '<input type="text" name="transformations[' + index + '][destination]" placeholder="Destination Address">';
// Add the remove button:
div.innerHTML += '<button type="button" onclick="removeTransformation(this)">Remove</button>';
container.appendChild(div);
}
function removeTransformation(button) {
button.parentNode.remove();
}
</script>
<div class="column">
<h2>Output JSON</h2>
<textarea name="output_json" rows="10" cols="30" readonly><?php echo $output_json ?></textarea>
<?php if (isset($error_message)): ?>
<div style="color: red;"><?php echo $error_message; ?></div>
<?php endif; ?>
</div>
</div>
<input type="submit" name="apply_transformations" value="Apply Transformations">
</form>
</body>
</html>
<?php
function getValueByAddress(&$array, $address) {
$keys = explode('.', $address);
$current = &$array;
foreach ($keys as $key) {
if (is_array($current) && isset($current[$key])) {
$current = &$current[$key];
} else {
return null;
}
}
return $current;
}
function filterJsonData($jsonData, $filterString) {
if (preg_match('/(\w+)\[(\w+)="([^"]+)"\](?:\.(\w+))?/', $filterString, $matches)) {
$itemName = $matches[1];
$property = $matches[2];
$value = $matches[3];
$subItem = isset($matches[4]) ? $matches[4] : null;
$filteredData = [];
foreach ($jsonData as $item) {
if (isset($item[$property]) && $item[$property] === $value) {
if ($subItem !== null && isset($item[$itemName][$subItem])) {
$filteredData[] = $item[$itemName][$subItem];
} else if ($subItem === null){
$filteredData[] = $item[$itemName];
}
}
}
return $filteredData;
} else {
return "Invalid filter string format";
}
}
function setValueByAddress(&$array, $source_address, $destination_address, $operation) {
$source_keys = explode('.', $source_address);
$dest_keys = explode('.', $destination_address);
$source_last_key = array_pop($source_keys);
$dest_last_key = array_pop($dest_keys);
$source_current = &$array;
$dest_current = &$array;
foreach ($source_keys as $key) {
if (!isset($source_current[$key]) || !is_array($source_current[$key])) {
return;
}
$source_current = &$source_current[$key];
}
foreach ($dest_keys as $key) {
if (!isset($dest_current[$key]) || !is_array($dest_current[$key])) {
$dest_current[$key] = [];
}
$dest_current = &$dest_current[$key];
}
if ($operation === 'copy') {
$dest_current[$dest_last_key] = $source_current[$source_last_key];
} elseif ($operation === 'move') {
$dest_current[$dest_last_key] = $source_current[$source_last_key];
unset($source_current[$source_last_key]);
if (empty($source_current) && count($source_keys) > 0) {
$parent_key = array_pop($source_keys);
$parent = &$array;
foreach ($source_keys as $key) {
$parent = &$parent[$key];
}
unset($parent[$parent_key]);
}
} elseif ($operation === 'remove'){
unset($source_current[$source_last_key]);
if (empty($source_current) && count($source_keys) > 0) {
$parent_key = array_pop($source_keys);
$parent = &$array;
foreach ($source_keys as $key) {
$parent = &$parent[$key];
}
unset($parent[$parent_key]);
}
}
}
?>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment