master
Jessa 2024-06-21 21:48:47 -07:00
commit 97914e4334
14 changed files with 930 additions and 0 deletions

4
.gitattributes vendored Normal file
View File

@ -0,0 +1,4 @@
.* export-ignore
*~ export-ignore
/config/config.php export-ignore
/jessa0-littleshlink-*.tar export-ignore

4
.gitignore vendored Normal file
View File

@ -0,0 +1,4 @@
/vendor
/littlelink-php/vendor
/config/config.php
/jessa0-littleshlink-*.tar

19
LICENSE Normal file
View File

@ -0,0 +1,19 @@
Copyright (c) 2024 jessa0
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

8
README.md Normal file
View File

@ -0,0 +1,8 @@
# Little Shlink
A PHP website displaying a list of links from a [Shlink](https://github.com/shlinkio/shlink) instance, utilizing the
[Littlelink](https://github.com/sethcottle/littlelink/) UI.
## License
Licensed under [MIT](https://opensource.org/licenses/MIT).

30
composer.json Normal file
View File

@ -0,0 +1,30 @@
{
"name": "jessa0/littleshlink",
"description": "A PHP website displaying a list of links from a Shlink instance, utilizing the Littlelink UI.",
"type": "project",
"license": "MIT",
"autoload": {
"psr-4": {
"Jessa0\\Littleshlink\\": "src/"
}
},
"require": {
"shlinkio/shlink-php-sdk": "^2.0",
"guzzlehttp/guzzle": "^7.0",
"jessa0/littlelink": "2.5.0"
},
"repositories": [
{
"type": "package",
"package": {
"name": "jessa0/littlelink",
"version": "2.5.0",
"source": {
"url": "https://github.com/sethcottle/littlelink.git",
"type": "git",
"reference": "tags/v2.5.0"
}
}
}
]
}

679
composer.lock generated Normal file
View File

@ -0,0 +1,679 @@
{
"_readme": [
"This file locks the dependencies of your project to a known state",
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "479acce3e42c35c520aa5540336aa2fc",
"packages": [
{
"name": "guzzlehttp/guzzle",
"version": "7.8.1",
"source": {
"type": "git",
"url": "https://github.com/guzzle/guzzle.git",
"reference": "41042bc7ab002487b876a0683fc8dce04ddce104"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/guzzle/guzzle/zipball/41042bc7ab002487b876a0683fc8dce04ddce104",
"reference": "41042bc7ab002487b876a0683fc8dce04ddce104",
"shasum": ""
},
"require": {
"ext-json": "*",
"guzzlehttp/promises": "^1.5.3 || ^2.0.1",
"guzzlehttp/psr7": "^1.9.1 || ^2.5.1",
"php": "^7.2.5 || ^8.0",
"psr/http-client": "^1.0",
"symfony/deprecation-contracts": "^2.2 || ^3.0"
},
"provide": {
"psr/http-client-implementation": "1.0"
},
"require-dev": {
"bamarni/composer-bin-plugin": "^1.8.2",
"ext-curl": "*",
"php-http/client-integration-tests": "dev-master#2c025848417c1135031fdf9c728ee53d0a7ceaee as 3.0.999",
"php-http/message-factory": "^1.1",
"phpunit/phpunit": "^8.5.36 || ^9.6.15",
"psr/log": "^1.1 || ^2.0 || ^3.0"
},
"suggest": {
"ext-curl": "Required for CURL handler support",
"ext-intl": "Required for Internationalized Domain Name (IDN) support",
"psr/log": "Required for using the Log middleware"
},
"type": "library",
"extra": {
"bamarni-bin": {
"bin-links": true,
"forward-command": false
}
},
"autoload": {
"files": [
"src/functions_include.php"
],
"psr-4": {
"GuzzleHttp\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Graham Campbell",
"email": "hello@gjcampbell.co.uk",
"homepage": "https://github.com/GrahamCampbell"
},
{
"name": "Michael Dowling",
"email": "mtdowling@gmail.com",
"homepage": "https://github.com/mtdowling"
},
{
"name": "Jeremy Lindblom",
"email": "jeremeamia@gmail.com",
"homepage": "https://github.com/jeremeamia"
},
{
"name": "George Mponos",
"email": "gmponos@gmail.com",
"homepage": "https://github.com/gmponos"
},
{
"name": "Tobias Nyholm",
"email": "tobias.nyholm@gmail.com",
"homepage": "https://github.com/Nyholm"
},
{
"name": "Márk Sági-Kazár",
"email": "mark.sagikazar@gmail.com",
"homepage": "https://github.com/sagikazarmark"
},
{
"name": "Tobias Schultze",
"email": "webmaster@tubo-world.de",
"homepage": "https://github.com/Tobion"
}
],
"description": "Guzzle is a PHP HTTP client library",
"keywords": [
"client",
"curl",
"framework",
"http",
"http client",
"psr-18",
"psr-7",
"rest",
"web service"
],
"support": {
"issues": "https://github.com/guzzle/guzzle/issues",
"source": "https://github.com/guzzle/guzzle/tree/7.8.1"
},
"funding": [
{
"url": "https://github.com/GrahamCampbell",
"type": "github"
},
{
"url": "https://github.com/Nyholm",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/guzzlehttp/guzzle",
"type": "tidelift"
}
],
"time": "2023-12-03T20:35:24+00:00"
},
{
"name": "guzzlehttp/promises",
"version": "2.0.2",
"source": {
"type": "git",
"url": "https://github.com/guzzle/promises.git",
"reference": "bbff78d96034045e58e13dedd6ad91b5d1253223"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/guzzle/promises/zipball/bbff78d96034045e58e13dedd6ad91b5d1253223",
"reference": "bbff78d96034045e58e13dedd6ad91b5d1253223",
"shasum": ""
},
"require": {
"php": "^7.2.5 || ^8.0"
},
"require-dev": {
"bamarni/composer-bin-plugin": "^1.8.2",
"phpunit/phpunit": "^8.5.36 || ^9.6.15"
},
"type": "library",
"extra": {
"bamarni-bin": {
"bin-links": true,
"forward-command": false
}
},
"autoload": {
"psr-4": {
"GuzzleHttp\\Promise\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Graham Campbell",
"email": "hello@gjcampbell.co.uk",
"homepage": "https://github.com/GrahamCampbell"
},
{
"name": "Michael Dowling",
"email": "mtdowling@gmail.com",
"homepage": "https://github.com/mtdowling"
},
{
"name": "Tobias Nyholm",
"email": "tobias.nyholm@gmail.com",
"homepage": "https://github.com/Nyholm"
},
{
"name": "Tobias Schultze",
"email": "webmaster@tubo-world.de",
"homepage": "https://github.com/Tobion"
}
],
"description": "Guzzle promises library",
"keywords": [
"promise"
],
"support": {
"issues": "https://github.com/guzzle/promises/issues",
"source": "https://github.com/guzzle/promises/tree/2.0.2"
},
"funding": [
{
"url": "https://github.com/GrahamCampbell",
"type": "github"
},
{
"url": "https://github.com/Nyholm",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/guzzlehttp/promises",
"type": "tidelift"
}
],
"time": "2023-12-03T20:19:20+00:00"
},
{
"name": "guzzlehttp/psr7",
"version": "2.6.2",
"source": {
"type": "git",
"url": "https://github.com/guzzle/psr7.git",
"reference": "45b30f99ac27b5ca93cb4831afe16285f57b8221"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/guzzle/psr7/zipball/45b30f99ac27b5ca93cb4831afe16285f57b8221",
"reference": "45b30f99ac27b5ca93cb4831afe16285f57b8221",
"shasum": ""
},
"require": {
"php": "^7.2.5 || ^8.0",
"psr/http-factory": "^1.0",
"psr/http-message": "^1.1 || ^2.0",
"ralouphie/getallheaders": "^3.0"
},
"provide": {
"psr/http-factory-implementation": "1.0",
"psr/http-message-implementation": "1.0"
},
"require-dev": {
"bamarni/composer-bin-plugin": "^1.8.2",
"http-interop/http-factory-tests": "^0.9",
"phpunit/phpunit": "^8.5.36 || ^9.6.15"
},
"suggest": {
"laminas/laminas-httphandlerrunner": "Emit PSR-7 responses"
},
"type": "library",
"extra": {
"bamarni-bin": {
"bin-links": true,
"forward-command": false
}
},
"autoload": {
"psr-4": {
"GuzzleHttp\\Psr7\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Graham Campbell",
"email": "hello@gjcampbell.co.uk",
"homepage": "https://github.com/GrahamCampbell"
},
{
"name": "Michael Dowling",
"email": "mtdowling@gmail.com",
"homepage": "https://github.com/mtdowling"
},
{
"name": "George Mponos",
"email": "gmponos@gmail.com",
"homepage": "https://github.com/gmponos"
},
{
"name": "Tobias Nyholm",
"email": "tobias.nyholm@gmail.com",
"homepage": "https://github.com/Nyholm"
},
{
"name": "Márk Sági-Kazár",
"email": "mark.sagikazar@gmail.com",
"homepage": "https://github.com/sagikazarmark"
},
{
"name": "Tobias Schultze",
"email": "webmaster@tubo-world.de",
"homepage": "https://github.com/Tobion"
},
{
"name": "Márk Sági-Kazár",
"email": "mark.sagikazar@gmail.com",
"homepage": "https://sagikazarmark.hu"
}
],
"description": "PSR-7 message implementation that also provides common utility methods",
"keywords": [
"http",
"message",
"psr-7",
"request",
"response",
"stream",
"uri",
"url"
],
"support": {
"issues": "https://github.com/guzzle/psr7/issues",
"source": "https://github.com/guzzle/psr7/tree/2.6.2"
},
"funding": [
{
"url": "https://github.com/GrahamCampbell",
"type": "github"
},
{
"url": "https://github.com/Nyholm",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/guzzlehttp/psr7",
"type": "tidelift"
}
],
"time": "2023-12-03T20:05:35+00:00"
},
{
"name": "jessa0/littlelink",
"version": "2.5.0",
"source": {
"type": "git",
"url": "https://github.com/sethcottle/littlelink.git",
"reference": "tags/v2.5.0"
},
"type": "library"
},
{
"name": "psr/http-client",
"version": "1.0.3",
"source": {
"type": "git",
"url": "https://github.com/php-fig/http-client.git",
"reference": "bb5906edc1c324c9a05aa0873d40117941e5fa90"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/php-fig/http-client/zipball/bb5906edc1c324c9a05aa0873d40117941e5fa90",
"reference": "bb5906edc1c324c9a05aa0873d40117941e5fa90",
"shasum": ""
},
"require": {
"php": "^7.0 || ^8.0",
"psr/http-message": "^1.0 || ^2.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.0.x-dev"
}
},
"autoload": {
"psr-4": {
"Psr\\Http\\Client\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "PHP-FIG",
"homepage": "https://www.php-fig.org/"
}
],
"description": "Common interface for HTTP clients",
"homepage": "https://github.com/php-fig/http-client",
"keywords": [
"http",
"http-client",
"psr",
"psr-18"
],
"support": {
"source": "https://github.com/php-fig/http-client"
},
"time": "2023-09-23T14:17:50+00:00"
},
{
"name": "psr/http-factory",
"version": "1.1.0",
"source": {
"type": "git",
"url": "https://github.com/php-fig/http-factory.git",
"reference": "2b4765fddfe3b508ac62f829e852b1501d3f6e8a"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/php-fig/http-factory/zipball/2b4765fddfe3b508ac62f829e852b1501d3f6e8a",
"reference": "2b4765fddfe3b508ac62f829e852b1501d3f6e8a",
"shasum": ""
},
"require": {
"php": ">=7.1",
"psr/http-message": "^1.0 || ^2.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.0.x-dev"
}
},
"autoload": {
"psr-4": {
"Psr\\Http\\Message\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "PHP-FIG",
"homepage": "https://www.php-fig.org/"
}
],
"description": "PSR-17: Common interfaces for PSR-7 HTTP message factories",
"keywords": [
"factory",
"http",
"message",
"psr",
"psr-17",
"psr-7",
"request",
"response"
],
"support": {
"source": "https://github.com/php-fig/http-factory"
},
"time": "2024-04-15T12:06:14+00:00"
},
{
"name": "psr/http-message",
"version": "2.0",
"source": {
"type": "git",
"url": "https://github.com/php-fig/http-message.git",
"reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/php-fig/http-message/zipball/402d35bcb92c70c026d1a6a9883f06b2ead23d71",
"reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71",
"shasum": ""
},
"require": {
"php": "^7.2 || ^8.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.0.x-dev"
}
},
"autoload": {
"psr-4": {
"Psr\\Http\\Message\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "PHP-FIG",
"homepage": "https://www.php-fig.org/"
}
],
"description": "Common interface for HTTP messages",
"homepage": "https://github.com/php-fig/http-message",
"keywords": [
"http",
"http-message",
"psr",
"psr-7",
"request",
"response"
],
"support": {
"source": "https://github.com/php-fig/http-message/tree/2.0"
},
"time": "2023-04-04T09:54:51+00:00"
},
{
"name": "ralouphie/getallheaders",
"version": "3.0.3",
"source": {
"type": "git",
"url": "https://github.com/ralouphie/getallheaders.git",
"reference": "120b605dfeb996808c31b6477290a714d356e822"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/ralouphie/getallheaders/zipball/120b605dfeb996808c31b6477290a714d356e822",
"reference": "120b605dfeb996808c31b6477290a714d356e822",
"shasum": ""
},
"require": {
"php": ">=5.6"
},
"require-dev": {
"php-coveralls/php-coveralls": "^2.1",
"phpunit/phpunit": "^5 || ^6.5"
},
"type": "library",
"autoload": {
"files": [
"src/getallheaders.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Ralph Khattar",
"email": "ralph.khattar@gmail.com"
}
],
"description": "A polyfill for getallheaders.",
"support": {
"issues": "https://github.com/ralouphie/getallheaders/issues",
"source": "https://github.com/ralouphie/getallheaders/tree/develop"
},
"time": "2019-03-08T08:55:37+00:00"
},
{
"name": "shlinkio/shlink-php-sdk",
"version": "v2.0.0",
"source": {
"type": "git",
"url": "https://github.com/shlinkio/shlink-php-sdk.git",
"reference": "6601a4d4265e1e0f08bf7440abb32ceda271a829"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/shlinkio/shlink-php-sdk/zipball/6601a4d4265e1e0f08bf7440abb32ceda271a829",
"reference": "6601a4d4265e1e0f08bf7440abb32ceda271a829",
"shasum": ""
},
"require": {
"php": "^8.2",
"psr/http-client": "^1.0",
"psr/http-factory": "^1.0"
},
"require-dev": {
"devster/ubench": "^2.1",
"guzzlehttp/guzzle": "^7.8",
"phpstan/phpstan": "^1.10",
"phpstan/phpstan-phpunit": "^1.3",
"phpunit/phpcov": "^10.0",
"phpunit/phpunit": "^11.0",
"roave/security-advisories": "dev-master",
"shlinkio/php-coding-standard": "~2.3.0",
"symfony/var-dumper": "^7.0"
},
"type": "library",
"autoload": {
"psr-4": {
"Shlinkio\\Shlink\\SDK\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Alejandro Celaya",
"email": "alejandro@alejandrocelaya.com",
"homepage": "https://www.alejandrocelaya.com"
}
],
"description": "A PHP SDK to consume Shlink's REST API",
"support": {
"issues": "https://github.com/shlinkio/shlink-php-sdk/issues",
"source": "https://github.com/shlinkio/shlink-php-sdk/tree/v2.0.0"
},
"time": "2024-03-11T20:12:53+00:00"
},
{
"name": "symfony/deprecation-contracts",
"version": "v3.5.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/deprecation-contracts.git",
"reference": "0e0d29ce1f20deffb4ab1b016a7257c4f1e789a1"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/0e0d29ce1f20deffb4ab1b016a7257c4f1e789a1",
"reference": "0e0d29ce1f20deffb4ab1b016a7257c4f1e789a1",
"shasum": ""
},
"require": {
"php": ">=8.1"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "3.5-dev"
},
"thanks": {
"name": "symfony/contracts",
"url": "https://github.com/symfony/contracts"
}
},
"autoload": {
"files": [
"function.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Nicolas Grekas",
"email": "p@tchwork.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "A generic function and convention to trigger deprecation notices",
"homepage": "https://symfony.com",
"support": {
"source": "https://github.com/symfony/deprecation-contracts/tree/v3.5.0"
},
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"time": "2024-04-18T09:32:20+00:00"
}
],
"packages-dev": [],
"aliases": [],
"minimum-stability": "stable",
"stability-flags": [],
"prefer-stable": false,
"prefer-lowest": false,
"platform": [],
"platform-dev": [],
"plugin-api-version": "2.6.0"
}

22
config/config-example.php Normal file
View File

@ -0,0 +1,22 @@
<?php
// The title of the site.
define('TITLE', "My Links");
// The path to a favicon to use for the site.
define('ICON', 'images/littlelink.png');
// The path to an avatar image to display on the site.
define('AVATAR', 'images/littlelink.svg');
// The path to a stylesheet to use for the site.
define('STYLESHEET', 'css/skeleton-auto.css');
// The base URL of the Shlink instance.
define('SHLINK_BASE_URL', 'https://example.com');
// The Shlink API key.
define('SHLINK_API_KEY', 'cec2f62c-b119-452a-b351-a416a2f5f45a');
// The Shlink tag put on short links to be displayed on the site.
define('SHLINK_TAG', 'index');

1
htdocs/css Symbolic link
View File

@ -0,0 +1 @@
../vendor/jessa0/littlelink/css

1
htdocs/fonts Symbolic link
View File

@ -0,0 +1 @@
../vendor/jessa0/littlelink/fonts

1
htdocs/images Symbolic link
View File

@ -0,0 +1 @@
../vendor/jessa0/littlelink/images

38
htdocs/index.php Normal file
View File

@ -0,0 +1,38 @@
<?php
declare(strict_types=1);
require_once __DIR__ . '/../vendor/autoload.php';
use Jessa0\Littleshlink\LittlelinkLink;
use Jessa0\Littleshlink\LittlelinkPage;
use Jessa0\Littleshlink\LittleshlinkPage;
if (file_exists(__DIR__ . '/../config/config.php')) {
require_once __DIR__ . '/../config/config.php';
}
if (!defined('TITLE')) {
define('TITLE', 'My Links');
}
if (!defined('ICON')) {
define('ICON', 'images/littlelink.png');
}
if (!defined('AVATAR')) {
define('AVATAR', 'images/littlelink.svg');
}
if (!defined('STYLESHEET')) {
define('STYLESHEET', 'css/skeleton-auto.css');
}
if (!defined('SHLINK_TAG')) {
define('SHLINK_TAG', 'index');
}
$littlelink_site = new LittlelinkPage(TITLE, ICON, AVATAR, STYLESHEET);
if (defined('SHLINK_BASE_URL') && defined('SHLINK_API_KEY')) {
$littleshlink_site = new LittleshlinkPage(SHLINK_BASE_URL, SHLINK_API_KEY, SHLINK_TAG);
$littleshlink_site->render($littlelink_site);
} else {
$littlelink_site->render([]);
}

15
src/LittlelinkLink.php Normal file
View File

@ -0,0 +1,15 @@
<?php
declare(strict_types=1);
namespace Jessa0\Littleshlink;
readonly class LittlelinkLink {
public function __construct(
public string $title,
public string $url,
public string $css_class,
public ?string $icon,
) {
}
}

55
src/LittlelinkPage.php Normal file
View File

@ -0,0 +1,55 @@
<?php
declare(strict_types=1);
namespace Jessa0\Littleshlink;
use Closure;
use Traversable;
readonly class LittlelinkPage {
public function __construct(
private string $title,
private string $icon,
private string $avatar,
private string $stylesheet,
) {
}
public function render(Traversable | array $links) {
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title><?= $this->title ?></title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="css/normalize.css">
<link rel="stylesheet" href="<?= $this->stylesheet ?>">
<link rel="stylesheet" href="css/brands.css">
<link rel="shortcut icon" href="<?= $this->icon ?>">
</head>
<body>
<div class="container">
<div class="row">
<div class="column" style="margin-top: 10%">
<img src="<?= $this->avatar ?>" class="avatar" srcset="<?= $this->avatar ?> 2x" alt="">
<h1 role="heading"><?= $this->title ?></h1>
<?php foreach ($links as $link) { ?>
<a class="button <?= $link->css_class ?>" href="<?= $link->url ?>" target="_blank" rel="noopener" role="button">
<?php if ($link->icon != null) { ?>
<img class="icon" aria-hidden="true" src="<?= $link->icon ?>">
<?php } ?>
<?= $link->title ?>
</a>
<br>
<?php } ?>
</div>
</div>
</div>
</body>
</html>
<?php
}
}

53
src/LittleshlinkPage.php Normal file
View File

@ -0,0 +1,53 @@
<?php
declare(strict_types=1);
namespace Jessa0\Littleshlink;
use Generator;
use GuzzleHttp\Client;
use GuzzleHttp\Psr7\HttpFactory;
use Shlinkio\Shlink\SDK\Config\ArrayShlinkConfig;
use Shlinkio\Shlink\SDK\Config\ShlinkConfig;
use Shlinkio\Shlink\SDK\Http\HttpClient;
use Shlinkio\Shlink\SDK\ShortUrls\Model\ShortUrlListOrderField;
use Shlinkio\Shlink\SDK\ShortUrls\Model\ShortUrlsFilter;
use Shlinkio\Shlink\SDK\ShortUrls\ShortUrlsClient;
use Shlinkio\Shlink\SDK\ShortUrls\Model\ShortUrl;
readonly class LittleshlinkPage {
private ArrayShlinkConfig $config;
public function __construct(string $base_url, string $api_key, private string $tag) {
$this->config = ShlinkConfig::fromArray([
'baseUrl' => $base_url,
'apiKey' => $api_key,
'version' => '3',
]);
}
public function links(): Generator {
$http = new HttpClient(new Client(), new HttpFactory(), new HttpFactory(), $this->config);
$client = new ShortUrlsClient($http);
$filter = ShortUrlsFilter::create()->containingSomeTags($this->tag);
foreach ($client->listShortUrlsWithFilter($filter) as $short_url) {
$css_class_suffix = 'default';
$icon = null;
foreach ($short_url->tags as $tag) {
if (str_starts_with($tag, 'index-class-')) {
$css_class_suffix = substr($tag, strlen('index-class-'));
}
if (str_starts_with($tag, 'index-icon-')) {
$icon = substr($tag, strlen('index-icon-'));
}
}
$title = $short_url->title ?? $short_url->shortCode;
yield new LittlelinkLink($title, $short_url->shortUrl, "button-$css_class_suffix", $icon);
}
}
public function render(LittlelinkPage $site) {
$site->render((fn(): Generator => yield from $this->links())());
}
}