Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/fix-code-styling.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ name: "Fix Code Styling"
on:
push:
branches:
- master
- '*.x'

jobs:
lint:
Expand Down
61 changes: 61 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
name: "Publish Release"

on:
push:
tags:
- 'v*'

permissions:
contents: write

jobs:
release:
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Determine release branch
id: branch
run: |
branch=$(git branch -r --contains "$GITHUB_SHA" --format='%(refname:short)' | sed 's#^origin/##' | grep -E '^[0-9]+\.x$' | head -n1)
if [ -z "$branch" ]; then
echo "Could not find a release branch containing $GITHUB_SHA" >&2
exit 1
fi
echo "branch=$branch" >> "$GITHUB_OUTPUT"

- name: Publish release
uses: softprops/action-gh-release@v2
Comment thread
jbrooksuk marked this conversation as resolved.
with:
generate_release_notes: true

- name: Fetch release notes
id: notes
env:
GH_TOKEN: ${{ github.token }}
run: |
{
echo 'body<<RELEASE_NOTES_EOF'
gh release view "$GITHUB_REF_NAME" --json body --jq .body
echo 'RELEASE_NOTES_EOF'
} >> "$GITHUB_OUTPUT"

- name: Switch to release branch
run: git checkout ${{ steps.branch.outputs.branch }}

- name: Update Changelog
uses: stefanzweifel/changelog-updater-action@v1
with:
latest-version: ${{ github.ref_name }}
release-notes: ${{ steps.notes.outputs.body }}

- name: Commit updated CHANGELOG
uses: stefanzweifel/git-auto-commit-action@v5
with:
branch: ${{ steps.branch.outputs.branch }}
commit_message: Update CHANGELOG
file_pattern: CHANGELOG.md
27 changes: 19 additions & 8 deletions .github/workflows/run-tests.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
name: run-tests

on: [push, pull_request]
on:
push:
branches:
- '*.x'
pull_request:

jobs:
test:
Expand All @@ -9,20 +13,27 @@ jobs:
fail-fast: true
matrix:
os: [ubuntu-latest]
php: [8.2, 8.1]
laravel: [10.*]
php: [8.2, 8.3, 8.4]
laravel: [12.*, 13.*]
stability: [prefer-lowest, prefer-stable]
include:
- laravel: 10.*
testbench: 8.*
pest: ^2.13
pest_laravel: ^2.0
- laravel: 12.*
testbench: 10.*
pest: ^3.0
pest_laravel: ^3.0
- laravel: 13.*
testbench: 11.*
pest: ^4.0
pest_laravel: ^4.0
exclude:
- laravel: 13.*
php: 8.2

name: P${{ matrix.php }} - L${{ matrix.laravel }} - ${{ matrix.stability }} - ${{ matrix.os }}

steps:
- name: Checkout code
uses: actions/checkout@v3
uses: actions/checkout@v4

- name: Setup PHP
uses: shivammathur/setup-php@v2
Expand Down
28 changes: 0 additions & 28 deletions .github/workflows/update-changelog.yml

This file was deleted.

3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Changelog

All notable changes to `cachethq/badger` will be documented in this file.
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ An SVG badge generator for Laravel.

## Installation

This version requires [PHP](https://php.net) 8.2 and Laravel 11.0 and above. For older versions of PHP or Laravel, check out the [3.x](https://github.com/cachethq/badger/tree/3.x) branch.
This version requires [PHP](https://php.net) 8.2 and Laravel 12.0 and above. For older versions of PHP or Laravel, check out the [4.x](https://github.com/cachethq/badger/tree/4.x) branch.

To get the latest version, simply require the project using [Composer](https://getcomposer.org):

Expand Down Expand Up @@ -46,12 +46,13 @@ The first parameter is the subject, or what it is the badge is showing. In the e
- `grey`
- `lightgray`

And finally the fourth parameter is the badge type. This determines the style of the badge and can be one of the four values below.
And finally the fourth parameter is the badge type. This determines the style of the badge and can be one of the five values below.

- `flat-square` (default)
- `plastic-flat`, `flat`
- `plastic`
- `social` (without links)
- `for-the-badge`

## Security

Expand Down
14 changes: 7 additions & 7 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,14 @@
}
],
"require": {
"php": "^8.0",
"illuminate/contracts": "^8.0|^9.0|^10.0",
"illuminate/support": "^8.0|^9.0|^10.0"
"php": "^8.2",
"illuminate/contracts": "^12.0|^13.0",
"illuminate/support": "^12.0|^13.0"
},
"require-dev": {
"orchestra/testbench": "^8.8",
"pestphp/pest": "^2.13",
"pestphp/pest-plugin-laravel": "^2.2"
"orchestra/testbench": "^10.0|^11.0",
"pestphp/pest": "^3.0|^4.0",
"pestphp/pest-plugin-laravel": "^3.0|^4.0"
},
"autoload": {
"psr-4": {
Expand All @@ -44,7 +44,7 @@
},
"extra": {
"branch-alias": {
"dev-master": "4.0-dev"
"dev-5.x": "5.0-dev"
},
"laravel": {
"providers": [
Expand Down
12 changes: 12 additions & 0 deletions resources/templates/for-the-badge.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 3 additions & 3 deletions src/Badge.php
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,9 @@ class Badge
/**
* Create a new badge instance.
*
* @throws \Cachet\Badger\Exceptions\InvalidHexColorException
* @throws InvalidHexColorException
*/
public function __construct(string $subject, string $status, string $color, string $format = null)
public function __construct(string $subject, string $status, string $color, ?string $format = null)
{
$this->subject = htmlspecialchars($subject, ENT_XML1, 'UTF-8');
$this->status = htmlspecialchars($status, ENT_XML1, 'UTF-8');
Expand All @@ -75,7 +75,7 @@ public function __construct(string $subject, string $status, string $color, stri
*/
public static function fromString(string $format): Badge
{
if (preg_match('/^(([^-]|--)+)-(([^-]|--)+)-(([^-]|--)+)\.(svg|png|gif|jpg)$/', $format, $match) === false && (7 != count($match))) {
if (preg_match('/^(([^-]|--)+)-(([^-]|--)+)-(([^-]|--)+)\.(svg|png|gif|jpg)$/', $format, $match) === false && (count($match) != 7)) {
throw new InvalidArgumentException('The given format string is invalid: '.$format);
}

Expand Down
8 changes: 4 additions & 4 deletions src/Badger.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,16 @@ class Badger
/**
* The available renderers.
*
* @var \Cachet\Badger\Render\RenderInterface[]
* @var RenderInterface[]
*/
protected array $renderers;

/**
* Create a new badger instance.
*
* @param \Cachet\Badger\Render\RenderInterface[] $renderers
* @param RenderInterface[] $renderers
*/
public function __construct(array $renderers = null)
public function __construct(?array $renderers = null)
{
foreach ($renderers as $renderer) {
$this->addRenderFormat($renderer);
Expand Down Expand Up @@ -61,7 +61,7 @@ protected function addRenderFormat(RenderInterface $renderer): void
/**
* Returns the renderer for the given format.
*
* @throws \Cachet\Badger\Exceptions\InvalidRendererException
* @throws InvalidRendererException
*/
protected function getRendererForFormat(string $format): RenderInterface
{
Expand Down
2 changes: 2 additions & 0 deletions src/BadgerServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use Cachet\Badger\Calculator\GDTextSizeCalculator;
use Cachet\Badger\Calculator\TextSizeCalculatorInterface;
use Cachet\Badger\Render\FlatSquareRender;
use Cachet\Badger\Render\ForTheBadgeRender;
use Cachet\Badger\Render\PlasticFlatRender;
use Cachet\Badger\Render\PlasticRender;
use Cachet\Badger\Render\SocialRender;
Expand Down Expand Up @@ -49,6 +50,7 @@ protected function registerBadger(): void
new PlasticRender($calculator, $path),
new PlasticFlatRender($calculator, $path),
new FlatSquareRender($calculator, $path),
new ForTheBadgeRender($calculator, $path),
new SocialRender($calculator, $path),
];

Expand Down
2 changes: 1 addition & 1 deletion src/Calculator/GDTextSizeCalculator.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public function __construct(string $path)
/**
* Calculate the width of the text box.
*/
public function calculateWidth(string $text, int $size = null): float
public function calculateWidth(string $text, ?int $size = null): float
{
$size = round(($size ?: static::TEXT_SIZE) * 0.75, 1);
$box = imagettfbbox($size, 0, $this->path, $text);
Expand Down
2 changes: 1 addition & 1 deletion src/Calculator/TextSizeCalculatorInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,5 +28,5 @@ interface TextSizeCalculatorInterface
/**
* Calculate the width of the text box.
*/
public function calculateWidth(string $text, int $size = null): float;
public function calculateWidth(string $text, ?int $size = null): float;
}
2 changes: 1 addition & 1 deletion src/Render/AbstractRender.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ abstract class AbstractRender implements RenderInterface
/**
* Create a new svg render instance.
*/
public function __construct(TextSizeCalculatorInterface $calculator, string $path, string $color = null)
public function __construct(TextSizeCalculatorInterface $calculator, string $path, ?string $color = null)
{
$this->calculator = $calculator;
$this->path = $path;
Expand Down
81 changes: 81 additions & 0 deletions src/Render/ForTheBadgeRender.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
<?php

namespace Cachet\Badger\Render;

use Cachet\Badger\Badge;
use Cachet\Badger\BadgeImage;

class ForTheBadgeRender extends AbstractRender
{
/**
* The additional horizontal padding applied to each section.
*/
protected const EXTRA_PADDING = 10;

/**
* The extra width added per character by the template's letter spacing.
*/
protected const LETTER_SPACING = 1;

/**
* Return a list of supported formats by the render.
*/
public function getSupportedFormats(): array
{
return ['for-the-badge'];
}

/**
* Render a badge.
*/
public function render(Badge $badge): BadgeImage
{
$subject = $this->uppercase($badge->subject());
$status = $this->uppercase($badge->status());

$subjectWidth = $this->sectionWidth($subject);
$statusWidth = $this->sectionWidth($status);

$params = [
'vendorWidth' => $subjectWidth,
'valueWidth' => $statusWidth,
'totalWidth' => $subjectWidth + $statusWidth,
'vendorColor' => $this->color,
'valueColor' => $badge->hexColor(),
'vendor' => $subject,
'value' => $status,
'vendorStartPosition' => round($subjectWidth / 2, 1) + 1,
'valueStartPosition' => $subjectWidth + round($statusWidth / 2, 1) - 1,
];

return $this->renderSvg($params, $badge->format());
}

/**
* Uppercase already XML-escaped text without corrupting its entities.
*/
protected function uppercase(string $text): string
{
return htmlspecialchars(
mb_strtoupper(htmlspecialchars_decode($text, ENT_XML1)),
ENT_XML1,
'UTF-8'
);
}

/**
* Calculate the width of a badge section, accounting for letter spacing and padding.
*/
protected function sectionWidth(string $text): float
{
return $this->stringWidth($text) + (mb_strlen($text) * self::LETTER_SPACING) + self::EXTRA_PADDING;
}

/**
* Returns the template contents.
*/
protected function getTemplate(): string
{
return 'for-the-badge.svg';
}
}
Loading
Loading