Skip to content

Commit 85be2df

Browse files
author
Pharaonic
committed
first commit
0 parents  commit 85be2df

File tree

10 files changed

+482
-0
lines changed

10 files changed

+482
-0
lines changed

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2020 Pharaonic. https://pharaonic.io
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
<p align="center"><a href="https://pharaonic.io" target="_blank"><img src="https://raw.githubusercontent.com/Pharaonic/logos/main/short-url.jpg" width="470"></a></p>
2+
3+
<p align="center">
4+
<a href="https://packagist.org/packages/Pharaonic/laravel-short-url"><img src="https://img.shields.io/packagist/v/RaggiTech/laravel-short-url" alt="Latest Stable Version"></a> <a href="https://packagist.org/packages/Pharaonic/laravel-short-url"><img src="https://img.shields.io/packagist/dt/Pharaonic/laravel-short-url" alt="Total Downloads"></a> <a href="https://packagist.org/packages/Pharaonic/laravel-short-url"><img src="https://img.shields.io/packagist/l/Pharaonic/laravel-short-url" alt="License"></a>
5+
</p>
6+
7+
8+
9+
## Install
10+
###### Laravel >= 8
11+
Install the latest version using [Composer](https://getcomposer.org/):
12+
13+
```bash
14+
$ composer require pharaonic/laravel-short-url
15+
$ php artisan vendor:publish --tag=laravel-short-url
16+
$ php artisan migrate
17+
```
18+
19+
20+
## Usage
21+
- [Generate (URL, Route)](#generate)
22+
- [Get URL](#read)
23+
- [IF Expired](#expired)
24+
- [Re-Generate Short URL](#regenerate)
25+
26+
27+
28+
<a name="generate" id="generate"></a>
29+
30+
#### Generate (URL, Route)
31+
32+
```php
33+
// Generate from URL
34+
shortURL()->generate('https://pharaonic.io');
35+
36+
// Generate from URL with Expiry date (string or Carbon object)
37+
shortURL()->generate('https://pharaonic.io', '2027-07-07');
38+
39+
40+
41+
// Generate from Route
42+
shortURL()->generate('route.name.here', ['param' => 1]);
43+
44+
// Generate from Route with Expiry date (string or Carbon object)
45+
shortURL()->generate('route.name.here', ['param' => 1]', '2027-07-07');
46+
```
47+
48+
49+
50+
<a name="read" id="read"></a>
51+
52+
#### Get URL
53+
54+
```php
55+
echo shortURL('3dc0c3deda')->url; // http://127.0.0.1:8000/8ca3522787
56+
57+
// Blade
58+
@shortURL('3dc0c3deda')
59+
```
60+
61+
62+
63+
<a name="expired" id="expired"></a>
64+
65+
#### IF Expired
66+
67+
```php
68+
shortURL('3dc0c3deda')->expired // false
69+
```
70+
71+
72+
73+
<a name="regenerate" id="regenerate"></a>
74+
75+
#### Re-Generate
76+
77+
```php
78+
shortURL('3dc0c3deda')->regenerate() // Returns ShortURL Object
79+
```
80+
81+
82+
## License
83+
84+
[MIT LICENSE](LICENSE.md)

composer.json

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
{
2+
"name": "pharaonic/laravel-short-url",
3+
"description": "Laravel - Short URL Generator { URL, Route }.",
4+
"keywords": [
5+
"php",
6+
"laravel",
7+
"short url",
8+
"pharaonic"
9+
],
10+
"license": "MIT",
11+
"authors": [
12+
{
13+
"name": "Raggi",
14+
"email": "support@pharaonic.io",
15+
"homepage": "https://pharaonic.io"
16+
}
17+
],
18+
"require": {
19+
"php": ">=7.0",
20+
"laravel/framework": ">=8.0"
21+
},
22+
"config": {
23+
"sort-packages": true
24+
},
25+
"extra": {
26+
"laravel": {
27+
"providers": [
28+
"Pharaonic\\Laravel\\ShortURL\\ShortURLServiceProvider"
29+
]
30+
}
31+
},
32+
"autoload": {
33+
"psr-4": {
34+
"Pharaonic\\Laravel\\ShortURL\\": "src"
35+
},
36+
"files": [
37+
"src/Helper.php"
38+
]
39+
},
40+
"minimum-stability": "dev",
41+
"prefer-stable": true
42+
}

src/Helper.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?php
2+
3+
use Pharaonic\Laravel\ShortURL\ShortURL;
4+
5+
/**
6+
* Short URL (Get OR New)
7+
*
8+
* @param string|null $code
9+
* @return ShortURL
10+
*/
11+
function shortURL(string $code = null) {
12+
if(!empty($code)) return ShortURL::where('code', $code)->first();
13+
14+
return new ShortURL;
15+
}

src/ShortURL.php

Lines changed: 195 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,195 @@
1+
<?php
2+
3+
namespace Pharaonic\Laravel\ShortURL;
4+
5+
use Carbon\Carbon;
6+
use Exception;
7+
use Illuminate\Database\Eloquent\Factories\HasFactory;
8+
use Illuminate\Database\Eloquent\Model;
9+
use Illuminate\Support\Facades\Route;
10+
11+
/**
12+
* Short URL Model
13+
*
14+
* @version 1.0
15+
* @author Raggi <support@pharaonic.io>
16+
* @license http://opensource.org/licenses/mit-license.php MIT License
17+
*/
18+
class ShortURL extends Model
19+
{
20+
use HasFactory;
21+
22+
/**
23+
* The table associated with the model.
24+
*
25+
* @var string
26+
*/
27+
protected $table = 'short_urls';
28+
29+
/**
30+
* The primary key for the model.
31+
*
32+
* @var string
33+
*/
34+
protected $primaryKey = 'code';
35+
36+
/**
37+
* The "type" of the primary key Code.
38+
*
39+
* @var string
40+
*/
41+
protected $keyType = 'string';
42+
43+
/**
44+
* Indicates if the IDs are auto-incrementing.
45+
*
46+
* @var bool
47+
*/
48+
public $incrementing = false;
49+
50+
/**
51+
* Table Columns
52+
*
53+
* @var array
54+
*/
55+
protected $fillable = ['code', 'type', 'data', 'user_id', 'expire_at'];
56+
57+
/**
58+
* Dates
59+
*
60+
* @var array
61+
*/
62+
protected $dates = ['expire_at'];
63+
64+
/**
65+
* Casts Columns
66+
*
67+
* @var array
68+
*/
69+
protected $casts = ['data' => 'array'];
70+
71+
72+
///////////////////////////////////////////////////////////////
73+
//
74+
// PRIVATE ACTIONS
75+
//
76+
///////////////////////////////////////////////////////////////
77+
78+
/**
79+
* Generate Code
80+
*
81+
* @return string
82+
*/
83+
private function generateCode()
84+
{
85+
// Generate Code
86+
$code = random_bytes(config('Pharaonic.short-url.length', 10) / 2);
87+
$code = bin2hex($code);
88+
89+
// Check Unique Code
90+
if (!$this->isUniqueCode($code)) return $this->generateCode();
91+
92+
return $code;
93+
}
94+
95+
/**
96+
* Check Code is Unique
97+
*
98+
* @return bool
99+
*/
100+
private function isUniqueCode(string $code)
101+
{
102+
return !self::where('code', $code)->exists();
103+
}
104+
105+
///////////////////////////////////////////////////////////////
106+
//
107+
// Custom Attributes
108+
//
109+
///////////////////////////////////////////////////////////////
110+
111+
/**
112+
* Has been Expired
113+
*
114+
* @return bool
115+
*/
116+
public function getExpiredAttribute()
117+
{
118+
if (!$this->code || !$this->expire_at) return false;
119+
120+
return $this->expire_at <= Carbon::now();
121+
}
122+
123+
/**
124+
* Undocumented function
125+
*
126+
* @return void
127+
*/
128+
public function getURLAttribute()
129+
{
130+
if (!$this->code) return null;
131+
132+
return route('shortURL', $this->code);
133+
}
134+
135+
///////////////////////////////////////////////////////////////
136+
//
137+
// PUBLIC ACTIONS
138+
//
139+
///////////////////////////////////////////////////////////////
140+
141+
/**
142+
* Get URL
143+
*
144+
* @return string
145+
*/
146+
public function __toString()
147+
{
148+
if (!$this->code) return null;
149+
150+
return $this->url ?? null;
151+
}
152+
153+
/**
154+
* Generate Short URL
155+
*
156+
* @param string $route route or url
157+
* @param array|string|null $params route params or expire date
158+
* @param string|Carbon $expire expire date
159+
* @return ShortURL
160+
*/
161+
public function generate(string $route, $params = null, $expire = null)
162+
{
163+
$isURL = filter_var($route, FILTER_VALIDATE_URL) !== false;
164+
165+
// Prepare Args
166+
if ($isURL && $params) $expire = $params;
167+
if (!$isURL && !Route::has($route)) throw new Exception("Route name has not been found!");
168+
if ($expire && !($expire instanceof Carbon)) $expire = Carbon::parse($expire);
169+
170+
171+
// Create ShortURL
172+
return self::create([
173+
'code' => $this->generateCode(),
174+
'type' => $isURL ? 'url' : 'route',
175+
'data' => $isURL ? ['url' => $route] : ['route' => $route] + ($params ? ['params' => $params] : []),
176+
'expire_at' => $expire,
177+
'user_id' => auth()->user() ? auth()->user()->id : null
178+
]);
179+
}
180+
181+
/**
182+
* Re-Generate Code
183+
*
184+
* @return ShortURL|null
185+
*/
186+
public function regenerate()
187+
{
188+
if (!$this->code) return null;
189+
190+
$this->code = $this->generateCode();
191+
$this->save();
192+
193+
return $this;
194+
}
195+
}

src/ShortURLController.php

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<?php
2+
3+
namespace Pharaonic\Laravel\ShortURL;
4+
5+
use App\Http\Controllers\Controller;
6+
use Pharaonic\Laravel\ShortURL\ShortURL;
7+
8+
/**
9+
* Short URL Controller
10+
*
11+
* @version 1.0
12+
* @author Raggi <support@pharaonic.io>
13+
* @license http://opensource.org/licenses/mit-license.php MIT License
14+
*/
15+
class ShortURLController extends Controller
16+
{
17+
/**
18+
* Redirec to IF NOT Expired
19+
*
20+
* @param ShortURL $ShortURL
21+
* @return void
22+
*/
23+
public function shortURL(ShortURL $ShortURL)
24+
{
25+
// Exipred ?
26+
if ($ShortURL->expired) return abort(404);
27+
28+
// Direct To
29+
return $ShortURL->type == 'url' ? redirect()->to($ShortURL->data['url']) : redirect()->route($ShortURL->data['route'], $ShortURL['params'] ?? []);
30+
}
31+
}

0 commit comments

Comments
 (0)