Created
October 13, 2025 14:53
-
-
Save nandordudas/3d0f05b9455a17c4069b3247fcb74627 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| RewriteEngine On | |
| RewriteRule ^updates\.json$ updates.php [L] |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| declare(strict_types=1); | |
| // https://extensionworkshop.com/documentation/manage/updating-your-extension/ | |
| // cat /proc/sys/kernel/random/uuid | |
| final readonly class Uuid | |
| { | |
| private function __construct(public string $value) {} | |
| public static function fromString(string $value): ?self | |
| { | |
| $pattern = '/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i'; | |
| return preg_match($pattern, $value) ? new self($value) : null; | |
| } | |
| public function withBraces(): string | |
| { | |
| return '{' . $this->value . '}'; | |
| } | |
| } | |
| final readonly class AddonUpdate | |
| { | |
| public function __construct( | |
| public string $version, | |
| public string $update_link, | |
| ) {} | |
| } | |
| final readonly class UpdatesGenerator | |
| { | |
| public function __construct( | |
| private string $addonsPath, | |
| private string $baseUrl, | |
| ) {} | |
| public function generate(): string | |
| { | |
| $addons = []; | |
| foreach (glob($this->addonsPath . '/*', GLOB_ONLYDIR) as $addonDir) { | |
| $uuid = Uuid::fromString(basename($addonDir)); | |
| if ($uuid === null) { | |
| continue; | |
| } | |
| $updates = $this->scanAddonUpdates($addonDir, $uuid); | |
| if ($updates !== []) { | |
| $addons[$uuid->withBraces()] = ['updates' => $updates]; | |
| } | |
| } | |
| return json_encode( | |
| ['addons' => $addons], | |
| JSON_UNESCAPED_SLASHES | JSON_THROW_ON_ERROR, | |
| ); | |
| } | |
| private function scanAddonUpdates(string $addonDir, Uuid $uuid): array | |
| { | |
| $updates = []; | |
| foreach (glob($addonDir . '/*.{zip,xpi}', GLOB_BRACE) as $file) { | |
| if (!preg_match('/^(.+)-(\d+\.\d+\.\d+)\.(zip|xpi)$/', $filename = basename($file), $matches)) { | |
| continue; | |
| } | |
| $updates[] = new AddonUpdate( | |
| version: $matches[2], | |
| update_link: $this->baseUrl . '/' . $uuid->value . '/' . $filename, | |
| ); | |
| } | |
| usort($updates, fn($a, $b) => version_compare($a->version, $b->version)); | |
| return array_map( | |
| fn(AddonUpdate $u) => [ | |
| 'version' => $u->version, | |
| 'update_link' => $u->update_link, | |
| ], | |
| $updates, | |
| ); | |
| } | |
| } | |
| function main(): void | |
| { | |
| $generator = new UpdatesGenerator( | |
| addonsPath: __DIR__, | |
| baseUrl: 'https://.../add-ons', | |
| ); | |
| header('Content-Type: application/json'); | |
| header('Cache-Control: max-age=60'); | |
| echo $generator->generate(); | |
| } | |
| // [TODO] add missing error handling | |
| main(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment