packages/requirements/src/Config/Markdown/StaticBadge.php
1<?php
2
3declare(strict_types=1);
4
5namespace Requirements\Config\Markdown;
6
7use Requirements\Input\InvalidInputException;
8
9/**
10 * Checks that a static shields.io badge image shows the value and role its alt text and
11 * title declare, so the rendered card cannot mislead.
12 */
13final class StaticBadge
14{
15 /**
16 * Checks a badge image; images from other hosts or paths are not checked.
17 *
18 * @param string $url The image URL
19 * @param string $field The field the badge sets
20 * @param string $value The value in its alt text
21 *
22 * @throws InvalidInputException When the static image shows another role or value
23 */
24 public static function validate(string $url, string $field, string $value): void
25 {
26 $path = rawurldecode((string) parse_url($url, PHP_URL_PATH));
27 if (parse_url($url, PHP_URL_HOST) !== 'img.shields.io' || preg_match('~^/badge/(kind|status|origin|category|label)-(.*)$~', $path, $match) !== 1) {
28 return;
29 }
30 $parts = explode('-', str_replace('--', "\0", $match[2]));
31 $message = str_replace(["\0", '_'], ['-', ' '], str_replace('__', "\1", $parts[0]));
32 $message = str_replace("\1", '_', $message);
33 if (count($parts) !== 2 || $match[1] !== $field || $message !== $value) {
34 throw new InvalidInputException('Static badge image text and role must agree with its alt text and title.');
35 }
36 }
37}
38