<?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 = []; $exclude = []; foreach( $lines as $line ) { $line = trim( $line ); if( $line === '' ) { continue; } if( $line[0] === '-' ) { $exclude[substr( $line, 1 )] = true; } else { $order[$line] = count( $order ); } } foreach( $repos as $key => $repo ) { if( isset( $exclude[$repo['safe_name']] ) ) { unset( $repos[$key] ); } } 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; } ); } }