skip to Main Content

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.

3

Answers


  1. 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.

    Login or Signup to reply.
  2. 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);
    }
    
    Login or Signup to reply.
  3. 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)
                );
            }
        }
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search