Group array by date from Json

Hi,
This is a php oriented question : I have a JSON file and I want to group each entries by date and echo each subject of the entries.

I found a working code on stackoverflow but my problem is : I can’t wrap every subjects into a unique div ! This code is taking only the first two entries, do you know why ??

<?php 
   $sortedData = array();
   foreach ($data_ai as $element): 
      $timestamp = strtotime($element->start->dateTime);
      $date = date("d.m.Y", $timestamp);    
   // from https://stackoverflow.com/questions/28964603/group-array-item-by-date-in-php-foreach
   ?>

   <?php if( ! isSet($sortedData[$date]) ):$sortedData[$date] = array($element); ?>
   <br><br>
   <?php echo  strftime("%A %d %B %Y", $timestamp); ?><br>
   <div style="border:2px solid red">
   <?php echo $element->subject ?><br>

   <?php else: $sortedData[$date][] = $element ?>
   <?php echo $element->subject ?><br>
   </div> 
   <?php endif ?>

   <?php endforeach ?>

This is what I get : https://olivierjonvaux.com/agenda/

What does the JSON file look like?

Yes, this is the Json file https://www.lefresnoy.net/pedagogie/calendar/export-calendar-json.php

I tried a different approach:

<?php 

$request = Remote::get('https://www.lefresnoy.net/pedagogie/calendar/export-calendar-json.php');

$results = $request->json(false);
$coll = new Collection($results);
$groupedItems = $coll->group(function($item) {
  if (! empty($item->start->dateTime)) {
    return date('Y-m-d', strtotime($item->start->dateTime));
  } else {
    return '';
  }
  
});
foreach($groupedItems as $date => $itemsPerDate): ?>
  <h2><?= $date ?></h2>
  <ul>
    <?php foreach($itemsPerDate as $item) : ?>
    <li><?= $item->subject ?></li>
    <?php endforeach; ?>
  </ul>
<?php endforeach ?>

Yeah it looks very good, but I don’t get any entries or date (I have copy-past your code) and don’t know where could be come from. Do you get something with this ?

Yes:

Oh waw ok, I was on Kirby 2.5.12 (Shame on me !!), but it’s working well on Kirby 3.
Don’t you know how could I implement it on Kirby 2 ?
Old habits die hard :grimacing: -> I have already made a json cache function and would like too stay on Kirby 2 for bad reasons…

But you already had some code to get the data? Could you post here how you arrived at $data_ai?

Yes for $data_ai, this is what I’ve done :

<?php 
    $data_ai = null;
    $cacheFile = kirby()->roots()->cache().DS.md5('agenda').'.json';
    if(!f::exists($cacheFile) ||
       ( f::exists($cacheFile) && (time() - f::modified($cacheFile) > c::get('cache.refresh', 3600)) )  
      ) {
       $url = 'https://www.lefresnoy.net/pedagogie/calendar/export-calendar-json.php';
       $data = file_get_contents($url);
       $data_ai = json_decode($data, true);
       f::write($cacheFile, $data);
    } else {
       $data_ai = json_decode(f::read($cacheFile)); 
    };
?>

If you change

$data_ai = json_decode($data, true);

to

$data_ai = json_decode($data, false); 

(and also in the cache file like)

the rest of my code should also work in Kirby 2

$coll = new Collection($data_ai);
$groupedItems = $coll->group(function($item) {
  if (! empty($item->start->dateTime)) {
    return date('Y-m-d', strtotime($item->start->dateTime));
  } else {
    return '';
  }
  
});
foreach($groupedItems as $date => $itemsPerDate): ?>
  <h2><?= $date ?></h2>
  <ul>
    <?php foreach($itemsPerDate as $item) : ?>
    <li><?= $item->subject ?></li>
    <?php endforeach; ?>
  </ul>
<?php endforeach ?>

Thank you some much for saving me my last five days !!!
Have a good night and dreams ! :wink:

1 Like