<?php class RepositoryList { private $reposPath; public function __construct($path) { $this->reposPath = $path; } public function eachRepository(callable $callback) { $repos = []; $dirs = glob($this->reposPath . '/*', GLOB_ONLYDIR); if ($dirs === false) return; foreach ($dirs as $dir) { $basename = basename($dir); if ($basename[0] === '.') continue; $repos[$basename] = [ 'name' => $basename, 'safe_name' => $basename, 'path' => $dir ]; } $this->sortRepositories($repos); foreach ($repos as $repo) { $callback($repo); } } private function sortRepositories(array &$repos) { $orderFile = __DIR__ . '/order.txt'; if (!file_exists($orderFile)) { ksort($repos, SORT_NATURAL | SORT_FLAG_CASE); return; } $lines = file($orderFile, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); $order = array_flip(array_map('trim', $lines)); uasort($repos, function($a, $b) use ($order) { $nameA = $a['safe_name']; $nameB = $b['safe_name']; $posA = $order[$nameA] ?? PHP_INT_MAX; $posB = $order[$nameB] ?? PHP_INT_MAX; if ($posA === $posB) { return strcasecmp($nameA, $nameB); } return $posA <=> $posB; }); } }