1

try to create or update a json file based on the processed data.

first I arrange the contents using assamble() and create a multidimensional array:

$logfile_accepted_array = [
    "AAAA 2022 12 23 21:37:56 dc:16:b2:4c:d2:e6",
    "BBB 2023 01 12 02:08:23 f0:8a:76:16:57:e8",
    "BBB 2023 02 19 17:34:33 a0:c9:a0:b6:79:3c",
    "AAAA 2023 02 23 12:21:09 f0:8a:76:16:57:e8",
    "AAAA 2023 02 23 18:15:10 f0:8a:76:16:57:e8",
    "CCCCC 2023 03 19 17:07:26 f0:8a:76:16:57:e8",
    "QQQ 2023 04 01 00:00:03 a0:c9:a0:b6:79:3c"
];

// Make directory and subdirectories ...
function dirMaker($directory, $sub_directory, $sub_sub_directory)
{
    if (!is_dir($directory . $sub_directory . $sub_sub_directory)) {
        mkdir(
            $directory . $sub_directory . $sub_sub_directory,
            0777,
            true
            // If true, then any parent directories 
            // to the directory specified will also be created, 
            // with the same permissions.
        );
    }
}

$root = 'archive/';

assemble data

function assemble($logfile_accepted_array)
{
    global $dailyData;

    # Get the colors for the zone 
    $getColors = file_get_contents('zones.json');
    $zoneColor = json_decode($getColors, true);
    // Group rows of data by column value then store nested data, first and last occurrences, and counts within each group
    foreach ($logfile_accepted_array as $row) {
        [$group, $date_year, $date_month_numeric, $day_digits, $time, $id] = explode(' ', $row);
        $result[$date_year][$date_month_numeric][$day_digits][$group]['user'][$id][] = $time;
    }

    $dailyData = $result;
}
assemble($logfile_accepted_array);

result

array (
  2022 => 
  array (
    12 => 
    array (
      23 => 
      array (
        'AAAA' => 
        array (
          'user' => 
          array (
            'dc:16:b2:4c:d2:e6' => 
            array (
              0 => '21:37:56',
            ),
          ),
        ),
      ),
    ),
  ),
  2023 => 
  array (
    '01' => 
    array (
      12 => 
      array (
        'BBB' => 
        array (
          'user' => 
          array (
            'f0:8a:76:16:57:e8' => 
            array (
              0 => '02:08:23',
            ),
          ),
        ),
      ),
    ),
/...

And now comes the big challenge:

  • create a y-m-d.json file in the respective directory (year/month) by iterating multidimensional array

In json files the year, month and day should not be omitted. But put in the correct year/month directory with which json filenames (y-m-d.json) are written.

function archiveJSON($logfile_accepted_array, $root, $dailyData)
{
    foreach ($logfile_accepted_array as $year_group) {
        [$group, $date_year, $date_month_numeric, $day_digits, $time, $id] = explode(' ', $year_group);
        $yearDir[$group][] = $date_year;
        $monthDir[$group][] = $date_month_numeric;
        $dayDir[$group][] = $day_digits;
        $user_id[$group][] = $id;
        $loged_time[$group][] = $time;

        dirMaker($root, $date_year . '/', $date_month_numeric . '/');
        $path = $root . $date_year . '/' . $date_month_numeric . '/';
        $json_file = $date_year . '-' . $date_month_numeric . '-' . $day_digits . '.json';

        if (!file_exists($path . $json_file)) {
            // Create a new json file in current date directory
            // and write data
            fopen($path . $json_file, 'w');
            file_put_contents($path . $json_file, json_encode($dailyData[$date_year][$date_month_numeric][$day_digits], JSON_PRETTY_PRINT));
        } else {
            # Existing Data
            $existing_json_file = file_get_contents($path . $json_file);
            $existing_array = json_decode($existing_json_file, true);

            foreach ($dailyData as $letter => $set) {
                if (!isset($existing_array[$letter])) {
                    $existing_array[$letter] = $set;
                } else {
                    $existing_array[$letter]['user'] = array_merge_recursive(
                        $existing_array[$letter]['user'],
                        $set['user']
                    );
                }
            }
            // update file
            file_put_contents($path . $json_file, json_encode($dailyData, JSON_PRETTY_PRINT));
        }
    }
}
archiveJSON($logfile_accepted_array, $root, $dailyData);

yes! if the directories (year/month) do not exist, they will be created if (!file_exists($path . $json_file)):

2022/12, 2023/1,2,3,4 and the json files with the right names (Y-m-d.json) in the right directory too.

expected json file content in 2023/02/2023-02-19.json:

{
    "BBB": {
        "user": {
            "a0:c9:a0:b6:79:3c": [
                "17:34:33"
            ]
        }
    }
}

expected json file content in 2023/02/2023-02-23.json:

{
    "AAAA": {
        "user": {
            "f0:8a:76:16:57:e8": ["12:21:09", "18:15:10"]
        }
    }
}

for the 1st i'm stuck here:

but if one of the letters has 2 entries on the same date as in this example: AAAA 2023 02 23 12:21:09 ... and AAAA 2023 02 23 18:15:10 ... then the 2023-02-23.json file all year entries written - unexpected json file content in 2023/02/2023-02-23.json:

{
    "2022": {
        "12": {
            "23": {
                "AAAA": {
                    "user": {
                        "dc:16:b2:4c:d2:e6": [
                            "21:37:56"
                        ]
                    }
                }
            }
        }
    },
    "2023": {
        "01": {
            "12": {
                "BBB": {
                    "user": {
                        "f0:8a:76:16:57:e8": [
                            "02:08:23"
                        ]
                    }
                }
            }
        },
        "02": {
            "19": {
                "BBB": {
                    "user": {
                        "a0:c9:a0:b6:79:3c": [
                            "17:34:33"
                        ]
                    }
                }
            },
            "23": {
                "AAAA": {
                    "user": {
                        "f0:8a:76:16:57:e8": [
                            "12:21:09",
                            "18:15:10"
                        ]
                    }
                }
            }
        },
        "03": {
            "19": {
                "CCCCC": {
                    "user": {
                        "f0:8a:76:16:57:e8": [
                            "17:07:26"
                        ]
                    }
                }
            }
        },
        "04": {
            "01": {
                "QQQ": {
                    "user": {
                        "a0:c9:a0:b6:79:3c": [
                            "00:00:03"
                        ]
                    }
                }
            }
        }
    }
}

else: if there are json data in the right directory with the right files, then complete them with the new entries:

secondly, I'm stuck here as well:

as above, all entries are written in each of the json files.

I would have to put $dailyData[$date_year][$date_month_numeric][$day_digits] in the right place. Or am I misunderstanding something?

i try many hours around. I spin around in circles.

Please don't be too harsh with me, because I'm an ambitious beginner and my head is getting tired.

Cem Firat
  • 390
  • 2
  • 21
  • About your first problem: You have described what you end up with. Can you provide a sample about what you would expect to end up with? – Lajos Arpad Feb 23 '23 at 11:32
  • I thought my explanation was clear. I'm trying to improve the description. what exactly is incomprehensible here? – Cem Firat Feb 23 '23 at 14:17
  • @LajosArpad, now: better explained and result I expect. i hope this more clearly – Cem Firat Feb 23 '23 at 16:37
  • Are the files already existent when you test? If they are: can you test without such files to see how new files would be created? – Lajos Arpad Feb 24 '23 at 12:47
  • Hello, I was ill and am well again. sorry if i'm raging late. I'm looking at it now. – Cem Firat Feb 28 '23 at 13:01

3 Answers3

1

You've presented a lot of code -- which I am finding difficult to read on my phone, but I believe your process is:

  1. Parse an array of lines and populate a multi-level hierarchical array
  2. Iterate the unique first 3 levels of the data structure, then
  3. Ensure that directories exist to accommodate the top three levels, then
  4. Access, decode, and recursively merge preexisting data in a given file (if it exists), then
  5. Save the new file contents.

Untested Suggested Code:

$fileLines = [
    "AAAA 2022 12 23 21:37:56 dc:16:b2:4c:d2:e6",
    "BBB 2023 01 12 02:08:23 f0:8a:76:16:57:e8",
    "BBB 2023 02 19 17:34:33 a0:c9:a0:b6:79:3c",
    "AAAA 2023 02 23 12:21:09 f0:8a:76:16:57:e8",
    "AAAA 2023 02 23 18:15:10 f0:8a:76:16:57:e8",
    "CCCCC 2023 03 19 17:07:26 f0:8a:76:16:57:e8",
    "QQQ 2023 04 01 00:00:03 a0:c9:a0:b6:79:3c"
];

$result = [];
foreach ($fileLines as $line) {
    [$group, $yyyy, $mm, $dd, $His, $id] = explode(' ', $line);
    $result[$yyyy][$mm][$dd][$group]['user'][$id][] = $His;
}

foreach ($result as $y => $months) {
    foreach ($months as $m => $days) {
        foreach ($days as $d => $groups) {
            $path = "$root/$y/$m";
            $filepath = "$path/$y-$m-$d.json";
            if (!file_exists($path)) {
                mkdir($path, 0777, true);
                $newContent = $groups;
            } elseif (!file_exists($filepath)) {
                $newContent = $groups;
            } else {
                $newContent = array_merge_recursive(
                    json_decode(file_get_contents($filepath), true),
                    $groups
                );
            }
            file_put_contents(
                $filepath,
                json_encode($newContent, JSON_PRETTY_PRINT)
            );
        }
    }
}
mickmackusa
  • 43,625
  • 12
  • 83
  • 136
  • thanks for your support. I implemented your suggestion and realized that: for example if the fileLines haven't changed: the existing time is added again. Expected: if the same prime time exists, then ignore - just add new ones: here the actual result: ```php {"QQQ": {"user": {"a0:c9:a0:b6:79:3c": ["00:00:03","00:00:03"]}}}``` I'm trying around, can't find a solution – Cem Firat Mar 01 '23 at 10:26
  • Might I recommend that you make the entire data path "associative"? `$result[$yyyy][$mm][$dd][$group]['user'][$id][$His] = $His;`? This way, you can enjoy the elegance of `array_replace_recursive()`. https://3v4l.org/6qVeu Alternatively, if you MUST have indexes in the lowest level, you could write more nested loops and call `array_unique()` after merging each bottom level -- not as elegant. – mickmackusa Mar 01 '23 at 12:05
  • ...the alternative/inelegant approach: https://3v4l.org/kZV1k – mickmackusa Mar 01 '23 at 12:21
  • the elegant variant, write this ```[21:37:56] => 21:37:56``` but indexing would be ```[0] => 21:37:56``` better? how can i handle with $oldContent? I didn't quite get it. https://3v4l.org/tBeO4#v8.2.3 – Cem Firat Mar 01 '23 at 14:53
  • If you want to try my first way, you'd need to adjust the old content already in files (to also be fully associative). If that is too much work, use the second way. – mickmackusa Mar 01 '23 at 18:01
  • 1
    I think I made it: https://3v4l.org/BE8uL#v8.2.3 – Cem Firat Mar 09 '23 at 09:29
0

The issue is that

file_put_contents($path . $json_file, json_encode($dailyData, JSON_PRETTY_PRINT));

prints the whole JSON. You need to refer to the correct path to your data in the else branch as well as you did in the if branch.

Lajos Arpad
  • 64,414
  • 37
  • 100
  • 175
0

Hope I didn't misunderstand your point.

If you want the 2023/02/2023-02-23.json file contains data like this:

{
    "AAAA": {
        "user": {
            "f0:8a:76:16:57:e8": [
                "12:21:09",
                "18:15:10"
            ]
        }
    }
}

then change these lines:

foreach ($dailyData as $letter => $set) {
    if (!isset($existing_array[$letter])) {
        $existing_array[$letter] = $set;
    } else {
        $existing_array[$letter]['user'] = array_merge_recursive(
            $existing_array[$letter]['user'],
            $set['user']
        );
    }
}
// update file
file_put_contents($path . $json_file, json_encode($dailyData, JSON_PRETTY_PRINT));

to:

foreach ($dailyData as $letter => $set) {
    if (isset($existing_array[$letter])) {
        $existing_array[$letter]['user'] = array_merge_recursive(
            $existing_array[$letter]['user'],
            $set['user']
        );
    }
}
// update file
file_put_contents($path . $json_file, json_encode($existing_array, JSON_PRETTY_PRINT));

OR

if you want the 2023/02/2023-02-23.json file contains data like this:

unexpected json file content in 2023-02-23.json

then change these lines:

...
} else {
    # Existing Data
    $existing_json_file = file_get_contents($path . $json_file);
    $existing_array = json_decode($existing_json_file, true);

    foreach ($dailyData as $letter => $set) {
        if (!isset($existing_array[$letter])) {
            $existing_array[$letter] = $set;
        } else {
            $existing_array[$letter]['user'] = array_merge_recursive(
                $existing_array[$letter]['user'],
                $set['user']
            );
        }
    }
    // update file
    file_put_contents($path . $json_file, json_encode($dailyData, JSON_PRETTY_PRINT));
}

to:

...
} else {
    // update file
    file_put_contents($path . $json_file, 'unexpected json file content in ' . $json_file);
}
Jordy
  • 1,802
  • 2
  • 6
  • 25