'LBRY', 'json_response' => true, 'cache' => $cache === true ? $twoHoursInSeconds : $cache]); } public static function listRoadmapChangesets($cache = true) { $sets = []; $allReleases = []; $project = 'lbry'; $page = 1; do { $releases = static::get('/repos/lbryio/' . $project . '/releases?page=' . $page, $cache); $page++; $allReleases = array_merge($allReleases, array_map(function ($release) use ($project) { return $release + ['project' => $project]; }, array_filter($releases, function ($release) { return ($release['tag_name'] ?? null) && ($release['published_at'] ?? null) && !$release['prerelease']; }))); } while (count($releases) >= 30); foreach ($allReleases as $release) { $group = null; $matches = null; if (preg_match('/^v(\d+)\.(\d+)\./', $release['tag_name'] ?? '', $matches)) { $group = 'v' . $matches[1] . '.' . $matches[2]; } if ($group) { $sets[$group][] = [ 'project' => $release['project'], 'date' => date('Y-m-d', strtotime($release['created_at'])), 'created_at' => $release['created_at'], 'name' => $release['name'] ?: $release['tag_name'], 'url' => $release['html_url'], 'version' => $release['tag_name'], 'body' => ParsedownExtra::instance()->text($release['body']) ]; } } uasort($sets, function ($sA, $sB) { return $sA[0]['created_at'] <=> $sB[0]['created_at']; }); foreach ($sets as $group => &$groupSet) { usort($groupSet, function ($rA, $rB) { return $rA['created_at'] <=> $rB['created_at']; }); } return $sets; } }