Search code examples
phparraysscopeexpressionengine

Nested arrays 'disappearing' in PHP/EECMS


I'm building a calendar which shows how busy members of a team are on every day of the month.

I have an array with people in it: $teammates.

Each teammate is another array, containing the name and another array with available days (Monday - Sunday):

{exp:channel:entries channel="teammates"}
$teammate = array();
$available_days = array();

{available_days} // this is a PT-checkbox field, it loops through a list of selected checkboxes (mon, tue, wed, etc).
array_push($available_days, "{option_name}");
{/available_days}

$teammate["name"] = "{title}";
$teammate["available_days"] = $available_days;
$teammate["workdays"] = array();

array_push($teammates, $teammate);
{/exp:channel:entries}

Now every month looks different. For example, the first of August is a Wednesday, where the first of September is a Saturday. That's why I also need to build an array of the current month, containing day name and day number pairs: [["day_name" => "wed", "day_number" => 1], ["day_name" => "thu", "day_number" => 2], ... etc]

This is done by using the {exp:channel:calendar} tag. Details aren't relevant. I end up with an array called $days_array_full.

The next step is to combine the days of the month with the available days for each teammate, so I end up with an array inside each $teammate containing the exact days that person is present, which I call "workdays". I do this as follows:

foreach($teammates as $teammate) {

    foreach($teammate["available_days"] as $available_day) {
        foreach($days_array_full as $day) {
            if($day["name"] == $available_day) {
                array_push($teammate["workdays"], array("name" => $day["name"], "number" => $day["number"]));
            }
        }

    }

    echo(count($teammate["workdays"]));
    // this echoes correct counts, such as about 25 for people who work 5 d/w.
}

But then, if I later on try to access a teammates $teammate["workdays"], the array is empty:

foreach($teammates as $teammate) {
    echo(count($teammate["workdays"]));
    // this always gives 0 for any teammate..., why?
}

I am guessing this is some kind of scope issue as ExpressionEngine executes the PHP code in eval(), but I can't really figure out what to change in order to make it work.


Solution

  • In order to use array_push the reference aready need to be an array. It simply means, you will need to initialize it:

    foreach($teammates as $key => $teammate) {
        $teammate["workdays"] = array();
        ...
    }
    

    Some more on that: Instead of using array_push you can use the following annotation:

    $teammate["workdays"][] = array("name" => $day["name"], "number" => $day["number"]);
    

    Finally that newly created array need to be written back to $teammates:

    foreach($teammates as $key => $teammate) {
        ...
        $teammates[$key] = $teammate;
    }
    

    But better you simply use $teammate as reference like this:

    foreach($teammates as &$teammate) {
        ...
    }