https://github.com/cleaniquecoders/shrinkr
Shrinkr is a Laravel package for shortening URLs, with custom slugs, analytics, branded domains, and seamless API integration.
https://github.com/cleaniquecoders/shrinkr
laravel php shortener
Last synced: 12 months ago
JSON representation
Shrinkr is a Laravel package for shortening URLs, with custom slugs, analytics, branded domains, and seamless API integration.
- Host: GitHub
- URL: https://github.com/cleaniquecoders/shrinkr
- Owner: cleaniquecoders
- License: mit
- Created: 2024-10-18T00:31:29.000Z (over 1 year ago)
- Default Branch: main
- Last Pushed: 2025-05-01T10:15:08.000Z (about 1 year ago)
- Last Synced: 2025-06-29T09:18:10.782Z (about 1 year ago)
- Topics: laravel, php, shortener
- Language: PHP
- Homepage:
- Size: 87.9 KB
- Stars: 12
- Watchers: 0
- Forks: 0
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- Funding: .github/FUNDING.yml
- License: LICENSE.md
Awesome Lists containing this project
README
[](https://packagist.org/packages/cleaniquecoders/shrinkr)
[](https://github.com/cleaniquecoders/shrinkr/actions?query=workflow%3Arun-tests+branch%3Amain)
[](https://github.com/cleaniquecoders/shrinkr/actions?query=workflow%3A"Fix+PHP+code+style+issues"+branch%3Amain)
[](https://packagist.org/packages/cleaniquecoders/shrinkr)
---
# Shrinkr
Shrinkr is a Laravel package for shortening URLs, offering custom slugs, analytics, branded domains, and API integration.
Shrinkr makes it easy to convert long URLs into short, shareable links. With features like **custom slugs**, **click analytics**, **branded domains**, and seamless **API support**, Shrinkr empowers users to manage URLs effectively.
---
## Features
- [x] **Shorten URLs** with or without custom slugs.
- [x] **Analytics tracking**: Track clicks, referrers, IP addresses, and devices.
- [x] **Branded domains**: Use custom domains for shortened URLs.
- [x] **Configurable logging**: Store logs in files or databases.
- [ ] **API support**: Programmatically shorten and resolve URLs.
- [x] ~~**Rate Limiting**: To prevent abuse (e.g., spamming requests to shorten URLs or resolve them).~~ **Middleware**: Added middleware configuration. Default is `throttle:60,1`.
- [ ] ~~**Protected URLs**: Add password protection or other access restrictions to certain URLs, ensuring only authorized users can access the content.~~ After further research, it's not relevant if the original URL is unprotected. Hence, this feature will be skip.
- [ ] ~~**QR Codes**: Provide users with QR codes for easy sharing of URLs, especially on mobile devices.~~ Use package such as [Simple QrCode](https://github.com/SimpleSoftwareIO/simple-qrcode) to generate the QR Code for the shortened URL.
- [x] **Link Health Monitoring**: Ensure that the original URLs are still reachable and valid & automatically disable or notify users if a link becomes broken or inactive.
- [x] **Event & Listeners**: Improve system decoupling by using events to trigger actions asynchronously (e.g., logging clicks, sending notifications).
- [x] **Expiry**: Allow expiry to be set - in minutes.
---
## Installation
Install the package via Composer:
```bash
composer require cleaniquecoders/shrinkr
```
Publish the migration files and migrate:
```bash
php artisan vendor:publish --tag="shrinkr-migrations"
php artisan migrate
```
Publish the config file:
```bash
php artisan vendor:publish --tag="shrinkr-config"
```
The published configuration file (`config/shrinkr.php`) will allow you to customize settings.
---
## Configuration
You can configure **logging options** by modifying the `config/shrinkr.php` file.
```php
return [
'logger' => \CleaniqueCoders\Shrinkr\Actions\Logger\LogToFile::class, // Default logger
];
```
To log to a **database**, change the logger to:
```php
'logger' => \CleaniqueCoders\Shrinkr\Actions\Logger\LogToDatabase::class,
```
---
## **Usage**
Here’s a basic usage example using the Shrinkr facade, actions, and events.
---
### **1. Shorten a URL**
You can shorten a URL with or without a **custom slug** and **expiry duration**.
```php
use CleaniqueCoders\Shrinkr\Facades\Shrinkr;
// Shorten a URL with default random slug
$shortUrl = Shrinkr::shorten('https://example.com/long-url', auth()->id());
echo $shortUrl; // Outputs: https://yourdomain.com/abc123
// Shorten a URL with a custom slug and expiry duration (e.g., 60 minutes)
$shortUrlWithCustomSlug = Shrinkr::shorten('https://example.com/long-url', auth()->id(), [
'custom_slug' => 'my-slug',
'expiry_duration' => 60, // Expires in 60 minutes
]);
echo $shortUrlWithCustomSlug; // Outputs: https://yourdomain.com/my-slug
```
---
### **2. Retrieve the Original URL**
Use the `resolve()` method to retrieve the **original URL** from a shortened one.
```php
$originalUrl = Shrinkr::resolve('abc123');
echo $originalUrl; // Outputs: https://example.com/long-url
```
When the URL is accessed, the **`UrlAccessed` event** will be dispatched automatically to track the visit.
---
### **3. Update an Existing Short URL**
You can update an existing short URL with a new **custom slug** or **expiry duration**.
```php
use CleaniqueCoders\Shrinkr\Models\Url;
use CleaniqueCoders\Shrinkr\Facades\Shrinkr;
$url = Url::find(1);
// Update the short URL with a new slug and expiry duration
$updatedUrl = Shrinkr::update($url, [
'custom_slug' => 'updated-slug',
'expiry_duration' => 120, // 2 hours from now
]);
echo $updatedUrl->shortened_url; // Outputs: https://yourdomain.com/updated-slug
```
---
### **4. Event Handling**
#### **UrlAccessed Event**
The **`UrlAccessed` event** is dispatched whenever a shortened URL is accessed. You can listen for this event to **log analytics or trigger notifications**.
**Example: Log URL Access in a Listener**
```php
namespace CleaniqueCoders\Shrinkr\Listeners;
use CleaniqueCoders\Shrinkr\Events\UrlAccessed;
use Illuminate\Support\Facades\Log;
class LogUrlAccess
{
public function handle(UrlAccessed $event)
{
$url = $event->url;
Log::info('URL accessed', [
'url_id' => $url->id,
'shortened_url' => $url->shortened_url,
'accessed_at' => now(),
]);
}
}
```
#### **UrlExpired Event**
The **`UrlExpired` event** is dispatched when a URL has expired, either through a scheduled check or upon access. You can listen to this event to **notify the user or perform other actions**.
**Example: Notify on URL Expiry in a Listener**
```php
namespace CleaniqueCoders\Shrinkr\Listeners;
use CleaniqueCoders\Shrinkr\Events\UrlExpired;
use Illuminate\Support\Facades\Log;
class NotifyUrlExpired
{
public function handle(UrlExpired $event)
{
$url = $event->url;
Log::warning('URL expired', [
'url_id' => $url->id,
'shortened_url' => $url->shortened_url,
'expired_at' => now(),
]);
// Optionally, notify the user about the expired URL.
}
}
```
---
### **5. Automatically Expire URLs**
If you’ve set an **expiry duration**, the URL will be marked as expired once that time has passed. You can also run the **expiry command** manually or schedule it.
**Run the Expiry Command Manually:**
```bash
php artisan shrinkr:check-expiry
```
**Schedule the Expiry Command:**
In your **`app/Console/Kernel.php`**:
```php
$schedule->command('shrinkr:check-expiry')->hourly();
```
---
### **6. Monitor URL Health**
The **Link Health Monitoring** feature allows you to **check if URLs are reachable** and mark them as **active or expired**.
#### **Check Health Action**
Use the `CheckUrlHealthAction` to **manually check the health** of a specific URL.
```php
use CleaniqueCoders\Shrinkr\Actions\CheckUrlHealthAction;
use CleaniqueCoders\Shrinkr\Models\Url;
$url = Url::find(1); // Retrieve URL instance
$action = new CheckUrlHealthAction();
$isHealthy = $action->execute($url);
if ($isHealthy) {
echo "URL is active.";
} else {
echo "URL is expired.";
}
```
#### **Check Health Command**
Use the Artisan command to **check the health of all URLs** in bulk.
```bash
php artisan shrinkr:check-health
```
This command will:
1. **Check the status** of all URLs.
2. **Mark expired URLs** and dispatch the `UrlExpired` event.
3. **Provide real-time output** on the status of each URL.
Example output:
```
URL abc123 is now marked as active.
URL xyz456 is now marked as expired.
URL health check completed.
```
#### **Schedule the Health Check Command**
You can **automatically run the health check** at regular intervals using Laravel’s scheduler.
In your **`app/Console/Kernel.php`**:
```php
protected function schedule(Schedule $schedule)
{
$schedule->command('shrinkr:check-health')->hourly();
}
```
This will ensure that all URLs are **continuously monitored** and marked as expired when necessary.
---
### **7. Redirect Tracking**
The redirect feature tracks detailed information such as:
- **IP address** of the visitor
- **Browser and OS** (via User-Agent parsing)
- **Referrer** (where the link was clicked)
- **Headers and query parameters**
- Optionally **store logs in a database** or log file
Example database log entry:
| url_id | ip | browser | platform | referrer | created_at |
|----------|------------|---------|----------|--------------|---------------------|
| 1 | 192.168.1.1 | Chrome | Windows | google.com | 2024-10-18 12:34:56 |
---
### **8. Routing**
You can configure custom domain for the URL by configuring:
```php
'domain' => 'bite.ly',
```
You may also change the middleware or add new one by configuring:
```php
'middleware' => ['auth', 'verified', 'throttle:600,1']
```
## Testing
Run the tests using:
```bash
composer test
```
---
## Changelog
Refer to the [CHANGELOG](CHANGELOG.md) for the latest updates and changes.
---
## Contributing
We welcome contributions! Please see [CONTRIBUTING](CONTRIBUTING.md) for guidelines.
---
## Security Vulnerabilities
Report security vulnerabilities by reviewing [our security policy](../../security/policy).
---
## Credits
- [Nasrul Hazim Bin Mohamad](https://github.com/nasrulhazim)
- [All Contributors](../../contributors)
---
## License
Shrinkr is open-sourced software licensed under the [MIT license](LICENSE.md).