Skip to content

Commit 338b85a

Browse files
committed
added support for Laravel 12 and new trait and methods
1 parent e71eb0f commit 338b85a

9 files changed

+1014
-58
lines changed

.github/workflows/run-tests.yml

+15-6
Original file line numberDiff line numberDiff line change
@@ -13,16 +13,24 @@ jobs:
1313
fail-fast: true
1414
matrix:
1515
os: [ubuntu-latest]
16-
php: [8.2]
17-
laravel: [11.*, 10.*]
16+
php: [8.2, 8.3]
17+
laravel: [11.*, 12.*]
1818
stability: [prefer-stable]
1919
include:
20+
- laravel: 12.*
21+
testbench: 10.*
22+
carbon: ^3.0
23+
larastan: ^3.0
24+
pest: ^3.7
25+
rector: ^2.0
26+
phpstan: ^2.0
2027
- laravel: 11.*
2128
testbench: 9.*
2229
carbon: ^3.0
23-
- laravel: 10.*
24-
testbench: 8.*
25-
carbon: ^2.63
30+
larastan: ^3.0
31+
pest: ^3.7
32+
rector: ^2.0
33+
phpstan: ^2.0
2634

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

@@ -44,7 +52,8 @@ jobs:
4452
4553
- name: Install dependencies
4654
run: |
47-
composer require "laravel/framework:${{ matrix.laravel }}" "orchestra/testbench:${{ matrix.testbench }}" "nesbot/carbon:${{ matrix.carbon }}" --no-interaction --no-update
55+
composer require "laravel/framework:${{ matrix.laravel }}" --no-interaction --no-update
56+
composer require --dev "orchestra/testbench:${{ matrix.testbench }}" "nesbot/carbon:${{ matrix.carbon }}" "phpstan/phpstan-phpunit:${{ matrix.phpstan }}" "larastan/larastan:${{ matrix.larastan }}" "pestphp/pest:${{ matrix.pest }}" "rector/rector:${{ matrix.rector }}" --no-interaction --no-update
4857
composer update --${{ matrix.stability }} --prefer-dist --no-interaction
4958
5059
- name: List Installed Dependencies

README.md

+297-11
Original file line numberDiff line numberDiff line change
@@ -26,18 +26,22 @@ This is the contents of the published config file:
2626
```php
2727

2828
return [
29-
/*
30-
|--------------------------------------------------------------------------
31-
| Default Number Range
32-
|--------------------------------------------------------------------------
33-
|
34-
| This option controls the default number range that will be used
35-
| when generating a random number.
36-
|
37-
*/
38-
39-
'from_number_range' => 1,
29+
/** This is the start of the random number range */
30+
'from_number_range' => 1000,
31+
/** This is the end of the random number range */
4032
'to_number_range' => 9999999,
33+
/** Prevent infinite recursion */
34+
'max_retries' => 100,
35+
/** Enable caching for the generated random numbers */
36+
'use_cache' => false,
37+
/** Cache time in seconds */
38+
'cache_time' => 60,
39+
/** Default pattern for generating random numbers */
40+
'default_pattern' => '#####',
41+
/** Maximum batch size for a single operation*/
42+
'max_batch_size' => 1000,
43+
/** Multiplier for candidate generation (higher means more candidates per batch) */
44+
'batch_candidate_multiplier' => 2,
4145
];
4246

4347
```
@@ -72,6 +76,288 @@ use CreativeCrafts\SecureRandomNumberGenerator\SecureRandomNumberGenerator;
7276
$secureUniqueRandomNumber = SecureRandomNumberGenerator::forModelUsingDefaultConfigNumberRange($tableName, $tableColumn)->generate();
7377

7478
```
79+
## New Features
80+
The Laravel Secure Random Number Generator package has been enhanced with several new methods and trait to provide more flexibility and functionality when generating secure random numbers.
81+
82+
## New Methods
83+
84+
### Batch Generation
85+
```php
86+
/**
87+
* Generates multiple secure random numbers within the configured range.
88+
*
89+
* @param int $count Number of unique random numbers to generate
90+
* @return array<int> Array of unique secure random numbers
91+
*
92+
* @throws RuntimeException If unable to generate enough unique numbers
93+
*/
94+
public function generateBatch(int $count): array;
95+
```
96+
97+
### Formatted Numbers
98+
```php
99+
/**
100+
* Generates a secure random number with optional prefix and suffix.
101+
*
102+
* @param string $prefix String to prepend to the number
103+
* @param string $suffix String to append to the number
104+
* @return string Formatted random number with prefix and suffix
105+
*/
106+
public function generateFormatted(string $prefix = '', string $suffix = ''): string;
107+
```
108+
109+
### Pattern-Based Numbers
110+
```php
111+
/**
112+
* Generates a secure random number formatted according to a pattern.
113+
*
114+
* The pattern uses # as a placeholder for each digit.
115+
* Example: "###-###" might produce "123-456"
116+
*
117+
* @param string $pattern Format pattern with # as digit placeholders
118+
* @return string Formatted random number
119+
*
120+
* @throws RuntimeException If pattern is invalid or number generation fails
121+
*/
122+
public function generateWithPattern(string $pattern): string;
123+
```
124+
125+
### Batch Formatted Numbers
126+
```php
127+
/**
128+
* Generates multiple secure random numbers with optional prefix and suffix.
129+
*
130+
* @param int $count Number of unique random numbers to generate
131+
* @param string $prefix String to prepend to each number
132+
* @param string $suffix String to append to each number
133+
* @return array<string> Array of formatted unique secure random numbers
134+
*
135+
* @throws RuntimeException If unable to generate enough unique numbers
136+
*/
137+
public function generateBatchFormatted(int $count, string $prefix = '', string $suffix = ''): array;
138+
```
139+
140+
### Batch Pattern-Based Numbers
141+
```php
142+
/**
143+
* Generates multiple secure random numbers formatted according to a pattern.
144+
*
145+
* @param int $count Number of unique random numbers to generate
146+
* @param string $pattern Format pattern with # as digit placeholders
147+
* @return array<string> Array of formatted unique secure random numbers
148+
*
149+
* @throws RuntimeException If unable to generate enough unique numbers
150+
*/
151+
public function generateBatchWithPattern(int $count, string $pattern): array;
152+
```
153+
154+
### Range Customization
155+
```php
156+
/**
157+
* Sets the minimum value for the random number range.
158+
*
159+
* @param int $min The minimum value (inclusive)
160+
*/
161+
public function min(int $min): self;
162+
163+
/**
164+
* Sets the maximum value for the random number range.
165+
*
166+
* @param int $max The maximum value (inclusive)
167+
*/
168+
public function max(int $max): self;
169+
```
170+
171+
### Uniqueness Validation
172+
```php
173+
/**
174+
* Sets the table and column for uniqueness validation.
175+
*
176+
* @param string $table The database table name
177+
* @param string $column The column name in the table
178+
*/
179+
public function uniqueIn(string $table, string $column): self;
180+
```
181+
182+
## Usage
183+
184+
### Generating Multiple Random Numbers
185+
```php
186+
// Generate 5 unique random numbers
187+
$numbers = SecureRandomNumberGenerator::useDefaultConfigNumberRange()
188+
->generateBatch(5);
189+
// Result: [12345, 67890, 54321, 98765, 13579]
190+
```
191+
192+
### Generating Formatted Numbers
193+
```php
194+
// Generate a random number with a specific pattern
195+
$phoneNumber = SecureRandomNumberGenerator::setNumberRange(0, 9)
196+
->generateWithPattern('###-###-####');
197+
// Result: "123-456-7890"
198+
```
199+
200+
### Generating Multiple Formatted Numbers
201+
```php
202+
// Generate 3 unique invoice numbers
203+
$invoiceNumbers = SecureRandomNumberGenerator::useDefaultConfigNumberRange()
204+
->generateBatchFormatted(3, 'INV-', '/2023');
205+
// Result: ["INV-12345/2023", "INV-67890/2023", "INV-54321/2023"]
206+
```
207+
208+
### Generating Multiple Pattern-Based Numbers
209+
```php
210+
// Generate 3 unique product codes
211+
$productCodes = SecureRandomNumberGenerator::setNumberRange(0, 9)
212+
->generateBatchWithPattern(3, 'PRD-###-###');
213+
// Result: ["PRD-123-456", "PRD-789-012", "PRD-345-678"]
214+
```
215+
216+
### Customizing Number Range
217+
```php
218+
// Generate a random number between 1000 and 9999
219+
$pinCode = SecureRandomNumberGenerator::useDefaultConfigNumberRange()
220+
->min(1000)
221+
->max(9999)
222+
->generate();
223+
// Result: 4567
224+
```
225+
226+
### Ensuring Uniqueness in Database
227+
```php
228+
// Generate a unique product code that doesn't exist in the database
229+
$productCode = SecureRandomNumberGenerator::setNumberRange(10000, 99999)
230+
->uniqueIn('products', 'product_code')
231+
->generate();
232+
// Result: 45678 (guaranteed to be unique in the products.product_code column)
233+
```
234+
235+
## Fluent Interface
236+
All methods can be chained for a fluent interface:
237+
238+
```php
239+
$result = SecureRandomNumberGenerator::setNumberRange(1, 999)
240+
->uniqueIn('orders', 'order_number')
241+
->min(100)
242+
->max(999)
243+
->generateFormatted('ORD-', '-2023');
244+
// Result: "ORD-123-2023" (unique in orders.order_number)
245+
```
246+
247+
## Error Handling
248+
The batch generation methods will throw a RuntimeException if they cannot generate the requested number of unique values after a reasonable number of attempts.
249+
Make sure to handle this exception in your code:
250+
251+
```php
252+
try {
253+
$numbers = SecureRandomNumberGenerator::setNumberRange(1, 10)
254+
->generateBatch(20); // Trying to generate 20 unique numbers from a range of only 10 possibilities
255+
} catch (RuntimeException $e) {
256+
// Handle the error - perhaps by increasing the range or decreasing the count
257+
Log::error('Failed to generate unique numbers: ' . $e->getMessage());
258+
}
259+
```
260+
261+
## Trait
262+
263+
### HasSecureRandomNumber
264+
This trait provides an easy way to automatically generate and assign secure random numbers to your Laravel Eloquent models.
265+
266+
## Usage
267+
268+
### Basic Usage
269+
Add the trait to any Eloquent model where you want to automatically generate a secure random number:
270+
271+
```php
272+
<?php
273+
274+
namespace App\Models;
275+
276+
use Illuminate\Database\Eloquent\Model;
277+
use CreativeCrafts\SecureRandomNumberGenerator\Traits\HasSecureRandomNumber;
278+
279+
class Order extends Model
280+
{
281+
use HasSecureRandomNumber;
282+
283+
// The rest of your model...
284+
}
285+
```
286+
287+
By default, the trait will:
288+
-Generate a secure random number when creating a new model instance
289+
-Store the number in a column named reference_number
290+
-Use the default number range from the package configuration
291+
292+
### Customizing the Column Name
293+
If you want to use a different column name for storing the random number, define the $randomNumberColumn property in your model:
294+
295+
```php
296+
<?php
297+
298+
namespace App\Models;
299+
300+
use Illuminate\Database\Eloquent\Model;
301+
use CreativeCrafts\SecureRandomNumberGenerator\Traits\HasSecureRandomNumber;
302+
303+
class Order extends Model
304+
{
305+
use HasSecureRandomNumber;
306+
307+
/**
308+
* The column that will store the random number.
309+
*
310+
* @var string
311+
*/
312+
protected $randomNumberColumn = 'order_number';
313+
314+
// The rest of your model...
315+
}
316+
```
317+
318+
### Database Migration
319+
Make sure to include the appropriate column in your migration:
320+
321+
```php
322+
<?php
323+
324+
use Illuminate\Database\Migrations\Migration;
325+
use Illuminate\Database\Schema\Blueprint;
326+
use Illuminate\Support\Facades\Schema;
327+
328+
return new class extends Migration
329+
{
330+
public function up()
331+
{
332+
Schema::create('orders', function (Blueprint $table) {
333+
$table->id();
334+
$table->string('reference_number')->unique(); // Default column name
335+
// or
336+
$table->string('order_number')->unique(); // Custom column name
337+
$table->timestamps();
338+
});
339+
}
340+
341+
public function down()
342+
{
343+
Schema::dropIfExists('orders');
344+
}
345+
};
346+
```
347+
348+
### Manually Generating Random Numbers
349+
You can also manually generate a random number for a model:
350+
351+
```php
352+
$randomNumber = Order::generateRandomNumber();
353+
```
354+
355+
How It Works
356+
The trait:
357+
1. Registers a creating event listener on the model
358+
2. When a new model is being created, it checks if the random number column is empty
359+
3. If empty, it generates a secure random number that is unique within the model's table
360+
4. Assigns the generated number to the specified column
75361

76362
## Testing
77363

0 commit comments

Comments
 (0)