Skip to content

Commit cf72adc

Browse files
committed
initial commit
0 parents  commit cf72adc

16 files changed

+530
-0
lines changed

.github/workflows/ci.yml

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
name: default
2+
3+
on:
4+
push:
5+
branches: [ main ]
6+
pull_request:
7+
branches: [ main ]
8+
9+
jobs:
10+
build:
11+
12+
runs-on: ubuntu-latest
13+
14+
strategy:
15+
matrix:
16+
php-version: [ '7.2', '7.3', '7.4', '8.0' ]
17+
laravel-version: [ '5.7.*', '5.8.*', '^6.0', '^7.0', '^8.0' ]
18+
exclude:
19+
- php-version: '7.2'
20+
laravel-version: '^8.0'
21+
- php-version: '7.4'
22+
laravel-version: '5.7.*'
23+
- php-version: '8.0'
24+
laravel-version: '5.7.*'
25+
- php-version: '8.0'
26+
laravel-version: '5.8.*'
27+
28+
name: Tests on PHP ${{ matrix.php-version }}
29+
30+
steps:
31+
- name: Checkout
32+
uses: actions/checkout@v2
33+
34+
- name: Setup PHP
35+
uses: shivammathur/setup-php@v2
36+
with:
37+
php-version: ${{ matrix.php-version }}
38+
39+
- name: Validate composer.json and composer.lock
40+
run: composer validate
41+
42+
- name: Cache Composer packages
43+
id: composer-cache
44+
uses: actions/cache@v2
45+
with:
46+
path: vendor
47+
key: ${{ runner.os }}-php-${{ matrix.php-version }}-${{ hashFiles('**/composer.lock') }}
48+
restore-keys: |
49+
${{ runner.os }}-php-${{ matrix.php-version }}-
50+
51+
- name: Install dependencies
52+
if: steps.composer-cache.outputs.cache-hit != 'true'
53+
run: composer install --prefer-dist --no-progress --no-suggest
54+
55+
- name: Install laravel/legacy-factories only for Laravel 8.0
56+
if: matrix.laravel-version == '^8.0'
57+
run: composer require "laravel/legacy-factories" --prefer-dist --no-progress --no-suggest
58+
59+
- name: Run test suite
60+
run: vendor/bin/phpunit --verbose

.gitignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
/.idea
2+
/vendor
3+
phpunit.xml
4+
.phpunit.result.cache
5+
composer.lock

LICENSE.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
The MIT License (MIT)
2+
3+
Copyright (c) Aleksei Zarubin
4+
5+
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:
6+
7+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
8+
9+
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.

README.md

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
# Laravel Human Readable Keys
2+
3+
[![Latest Version on Packagist](https://img.shields.io/packagist/v/tailflow/laravel-human-readable-keys.svg)](https://packagist.org/packages/tailflow/laravel-human-readable-keys)
4+
[![Build Status on Travis CI](https://img.shields.io/github/workflow/status/tailflow/laravel-human-readable-keys/default)](https://github.com/tailflow/laravel-human-readable-keys/actions)
5+
6+
Have you ever wanted to generate Stripe-like IDs for your Eloquent models? This package does exactly that!
7+
8+
## Installation
9+
10+
You can install the package via composer:
11+
12+
```bash
13+
composer require tailflow/laravel-human-readable-keys
14+
```
15+
16+
## Usage
17+
18+
1. Change type of the `id` (or whatever your primary key column is) to `string` in the migration
19+
20+
```php
21+
Schema::create('users', function (Blueprint $table) {
22+
$table->string()('id');
23+
24+
...
25+
});
26+
```
27+
28+
2. Add `HasHumanReadableKey` trait to a model
29+
30+
```php
31+
<?php
32+
33+
namespace App\Models;
34+
35+
use Illuminate\Database\Eloquent\Model;
36+
use Tailflow\HumanReadableKeys\Concerns\HasHumanReadableKey;
37+
38+
class User extends Model
39+
{
40+
use HasHumanReadableKey;
41+
42+
...
43+
}
44+
```
45+
46+
3. (Optional) Customize key prefix and length
47+
48+
By default, a singular form of the table name is used as prefix for generated keys. You can customize that by overriding
49+
the `getKeyPrefix` method on the model:
50+
51+
```php
52+
<?php
53+
54+
namespace App\Models;
55+
56+
use Illuminate\Database\Eloquent\Model;
57+
use Tailflow\HumanReadableKeys\Concerns\HasHumanReadableKey;
58+
59+
class User extends Model
60+
{
61+
use HasHumanReadableKey;
62+
63+
...
64+
65+
public function getKeyPrefix(): string
66+
{
67+
return 'account';
68+
}
69+
}
70+
```
71+
72+
Generated keys contain a unique hash that is 24 characters in length. To customize hash length, override the `getKeyLength` method:
73+
74+
```php
75+
<?php
76+
77+
namespace App\Models;
78+
79+
use Illuminate\Database\Eloquent\Model;
80+
use Tailflow\HumanReadableKeys\Concerns\HasHumanReadableKey;
81+
82+
class User extends Model
83+
{
84+
use HasHumanReadableKey;
85+
86+
...
87+
88+
public function getKeyLength(): string
89+
{
90+
return 16;
91+
}
92+
}
93+
```
94+
95+
## License
96+
97+
The MIT License (MIT). Please see [License File](LICENSE.md) for more information.

composer.json

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
{
2+
"name": "tailflow/laravel-human-readable-keys",
3+
"keywords": [
4+
"tailflow",
5+
"laravel stripe id",
6+
"laravel human id",
7+
"laravel string id"
8+
],
9+
"homepage": "https://github.com/tailflow/laravel-human-readable-keys",
10+
"description": "Generate Stripe-like IDs for Eloquent models",
11+
"type": "library",
12+
"license": "MIT",
13+
"authors": [
14+
{
15+
"name": "Aleksei Zarubin",
16+
"email": "[email protected]"
17+
}
18+
],
19+
"require": {
20+
"php": ">=7.1",
21+
"illuminate/contracts": ">=5.7",
22+
"illuminate/database": ">=5.7",
23+
"illuminate/support": ">=5.7"
24+
},
25+
"require-dev": {
26+
"mockery/mockery": "^1.0",
27+
"phpunit/phpunit": "^6.0|^7.0|^8.0|^9.0",
28+
"orchestra/testbench": "^3.7|^4.0|^5.0|^6.0"
29+
},
30+
"extra": {
31+
"laravel": {
32+
"providers": [
33+
"Tailflow\\HumanReadableKeys\\HumanReadableKeysServiceProvider"
34+
]
35+
}
36+
},
37+
"config": {
38+
"sort-packages": true
39+
},
40+
"autoload": {
41+
"psr-4": {
42+
"Tailflow\\HumanReadableKeys\\": "src"
43+
}
44+
},
45+
"autoload-dev": {
46+
"psr-4": {
47+
"Tailflow\\HumanReadableKeys\\Tests\\": "tests",
48+
"Tailflow\\HumanReadableKeys\\Tests\\Fixtures\\App\\": "tests/fixtures/app/",
49+
"Tailflow\\HumanReadableKeys\\Tests\\Fixtures\\Database\\Factories\\": "tests/fixtures/database/factories"
50+
}
51+
},
52+
"support": {
53+
"issues": "https://github.com/tailflow/laravel-human-readable-keys/issues",
54+
"source": "https://github.com/tailflow/laravel-human-readable-keys"
55+
}
56+
}

phpunit.xml.dist

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<phpunit backupGlobals="false"
3+
backupStaticAttributes="false"
4+
beStrictAboutTestsThatDoNotTestAnything="false"
5+
bootstrap="vendor/autoload.php"
6+
colors="true"
7+
convertErrorsToExceptions="true"
8+
convertNoticesToExceptions="true"
9+
convertWarningsToExceptions="true"
10+
processIsolation="false"
11+
stopOnFailure="false"
12+
>
13+
<php>
14+
<env name="DB_CONNECTION" value="testing"/>
15+
</php>
16+
<filter>
17+
<whitelist processUncoveredFilesFromWhitelist="true">
18+
<directory suffix=".php">./src</directory>
19+
</whitelist>
20+
</filter>
21+
<testsuites>
22+
<testsuite name="Package Test Suite">
23+
<directory suffix="Test.php">./tests</directory>
24+
</testsuite>
25+
</testsuites>
26+
</phpunit>

src/Concerns/HasHumanReadableKey.php

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Tailflow\HumanReadableKeys\Concerns;
6+
7+
use Illuminate\Contracts\Container\BindingResolutionException;
8+
use Illuminate\Support\Str;
9+
use Tailflow\HumanReadableKeys\Contracts\KeyGenerator;
10+
11+
trait HasHumanReadableKey
12+
{
13+
/**
14+
* @throws BindingResolutionException
15+
*/
16+
protected static function bootHasHumanReadableKey(): void
17+
{
18+
static::creating(function ($model) {
19+
if (!$model->getKey()) {
20+
$model->{$model->getKeyName()} = app()->make(KeyGenerator::class)->generate(
21+
$model->getKeyPrefix(),
22+
$model->getKeyLength()
23+
);
24+
}
25+
});
26+
}
27+
28+
public function getKeyPrefix(): string
29+
{
30+
return Str::singular($this->getTable());
31+
}
32+
33+
public function getKeyLength(): int
34+
{
35+
return 24;
36+
}
37+
38+
public function getIncrementing()
39+
{
40+
return false;
41+
}
42+
43+
public function getKeyType()
44+
{
45+
return 'string';
46+
}
47+
}

src/Contracts/KeyGenerator.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Tailflow\HumanReadableKeys\Contracts;
6+
7+
interface KeyGenerator
8+
{
9+
public function generate(string $prefix, int $length): string;
10+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Tailflow\HumanReadableKeys\Generators;
6+
7+
use Illuminate\Support\Str;
8+
use Tailflow\HumanReadableKeys\Contracts\KeyGenerator as KeyGeneratorContract;
9+
10+
class DefaultKeyGenerator implements KeyGeneratorContract
11+
{
12+
public function generate(string $prefix, int $length): string
13+
{
14+
$uniqueHash = Str::random($length);
15+
16+
return "{$prefix}_{$uniqueHash}";
17+
}
18+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Tailflow\HumanReadableKeys;
6+
7+
use Illuminate\Support\ServiceProvider;
8+
use Tailflow\HumanReadableKeys\Contracts\KeyGenerator as KeyGeneratorContract;
9+
use Tailflow\HumanReadableKeys\Generators\DefaultKeyGenerator;
10+
11+
class HumanReadableKeysServiceProvider extends ServiceProvider
12+
{
13+
/**
14+
* Register bindings in the container.
15+
*
16+
* @return void
17+
*/
18+
public function register()
19+
{
20+
$this->app->bind(KeyGeneratorContract::class, DefaultKeyGenerator::class);
21+
}
22+
}

tests/HasHumanReadableKeyTest.php

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Tailflow\HumanReadableKeys\Tests;
6+
7+
use Mockery;
8+
use Tailflow\HumanReadableKeys\Generators\DefaultKeyGenerator;
9+
use Tailflow\HumanReadableKeys\Tests\Fixtures\App\Models\User;
10+
use Tailflow\HumanReadableKeys\Contracts\KeyGenerator as KeyGeneratorContract;
11+
12+
class HasHumanReadableKeyTest extends TestCase
13+
{
14+
/** @test */
15+
public function generating_key_on_model_creation(): void
16+
{
17+
$keyGeneratorMock = Mockery::mock(DefaultKeyGenerator::class);
18+
$keyGeneratorMock->expects('generate')
19+
->with('user', 24)
20+
->once()
21+
->andReturn('test-human-readable-key');
22+
23+
app()->instance(KeyGeneratorContract::class, $keyGeneratorMock);
24+
25+
$user = factory(User::class)->create();
26+
27+
self::assertSame('test-human-readable-key', $user->getKey());
28+
}
29+
}

0 commit comments

Comments
 (0)