PHPackages                             poing/earmark - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Database &amp; ORM](/categories/database)
4. /
5. poing/earmark

ActiveLibrary[Database &amp; ORM](/categories/database)

poing/earmark
=============

Laravel package to generate values in a unique and customizable series.

0.2.2(1y ago)10712.9k↓50%6[2 issues](https://github.com/poing/earmark/issues)MITPHPPHP &gt;=8.1

Since Jun 4Pushed 1y ago1 watchersCompare

[ Source](https://github.com/poing/earmark)[ Packagist](https://packagist.org/packages/poing/earmark)[ Docs](https://github.com/poing/earmark)[ RSS](/packages/poing-earmark/feed)WikiDiscussions master Synced 1mo ago

READMEChangelog (10)Dependencies (8)Versions (24)Used By (0)

[![StyleCI](https://camo.githubusercontent.com/1479bd8ec74678feca7ae26861cb504b01d5b2e8bd82dbc832f20abeb6f443fd/68747470733a2f2f6769746875622e7374796c6563692e696f2f7265706f732f3139303132383334352f736869656c643f6272616e63683d302e312e38267374796c653d666c6174)](https://github.styleci.io/repos/190128345)[![Coverage Status](https://camo.githubusercontent.com/ddd4fa1f065bea335dbbb38735d0f33ae17be15a1f836c89639a6d5f707f31cb/68747470733a2f2f636f766572616c6c732e696f2f7265706f732f6769746875622f706f696e672f6561726d61726b2f62616467652e7376673f6272616e63683d302e312e38)](https://coveralls.io/github/poing/earmark?branch=master)

Earmark
=======

[](#earmark)

A Laravel package to earmark sequential values in a series and eliminate any gaps in the series when values are `unset`. *Allowing for values to be reused.*

It can be used to fetch the next value (or array of values) to be used in an application. Database locking is used to *prevent* duplicate values from being returned.

An example...
=============

[](#an-example)

Reserving the next available phone extension for a user. The phone extension can be reserved by the active session, preventing other sessions from obtaining the same value.

When a user leaves the phone extension can be *recycled*, the value can be `unset()`. Making the value available again for a *future* request.

Getting Started
===============

[](#getting-started)

1. Install EarMark
------------------

[](#1-install-earmark)

Run this at the command line:

```
composer require poing/earmark

```

This will update composer.json and install the package into the vendor/ directory.

2. Publish the EarMark Configuration File
-----------------------------------------

[](#2-publish-the-earmark-configuration-file)

To over-ride the default settings, initialize the config file by running this command:

```
php artisan earmark:config

```

Then open config/earmark.php and edit the settings to meet the requirements of your application.

3. Run the Migrations
---------------------

[](#3-run-the-migrations)

Run the package migration files at the command line:

```
php artisan migrate

```

4. Recommended
--------------

[](#4-recommended)

This package is designed to use Laravel Queues, to defer the time consuming task of repopulating the available pool of values.

You may want to change the default `QUEUE_CONNECTION` to use another strategy. But the package *also* works with the default `sync`, but **may** cause latency in your application.

Settings
========

[](#settings)

Hold Size
---------

[](#hold-size)

This is the number of series values that are kept in an available pool. Once the pool drops below a certain level, more values are added to the pool. *This is where unused values are recycled.*

### Important:

[](#important)

- Replenishing the hold **will** be time consuming and *may* take **minutes** to complete.
- Depending on how you use Earmark, the hold size should be a *multiple* of the **maximum** `get()` requests expected.
- Hold size *should* be configured to allow for a sufficient number of `get()` requests **after** falling below one-third.

Number Range
------------

[](#number-range)

This package *currently* supports a minimal value. `range.min` will define the starting value of the series. *Default: 2000*

```
2000
2001
2002
2003

```

*`range.max` may be used in the future.*

Zero Padding
------------

[](#zero-padding)

Allows the output value to be zero-padded, depending on the needs of the application.

```
2004
002005
00000000002006

```

Prefix &amp; Suffix
-------------------

[](#prefix--suffix)

Appends a *prefix* to the output value.

```
ALPHA2007
ALPHA002008
ALPHA00000000002009

```

*`suffix` may be used in the future.*

How to Use
==========

[](#how-to-use)

There are two ways to use this package:

- `Earmarked` to use the *default* values in the pool. *The default values are already "Earmarked".*
- `Earmark` to create a **new** pool of values to use. *Use custom settings with a new "Earmark".*

Available Functions:

- `get()`
    - Returns a *single* formated value.
    - Will accept *option* integer to return an array of formatted values.
- `unset($value)`
    - Accepts *formated* values as a string or array.

Simple Usage
------------

[](#simple-usage)

With the values from the configuration file, use `Earmarked::get()` and `Earmarked::unset()`.

```
$serial = Earmarked::get(); // Returns: '2010'
Earmarked::unset($serial);
```

You can also *specify* the number of values to return in an array:

```
$serial = Earmarked::get(3); // Returns: [ '2011', '2012', '2013', ]
Earmarked::unset($serial);
```

Advanced Usage
--------------

[](#advanced-usage)

You can *initialize* a **new** series using `Earmark()` and supplying the following variables:

- prefix
- suffix *(non-functional placeholder)*
- padding
- min
- max *(non-functional placeholder)*

```
// Earmark(prefix, suffix, padding, min, max)
$earmark = new Earmark('ZULU', null, 10, 5000, null);
$earmark->get(); // Returns: 'ZULU0000005000'
$earmark->get(3); // Returns: [ 'ZULU0000005001', 'ZULU0000005002', 'ZULU0000005003', ]
```

*The new series will not affect the default series, calling the series again **(with the same parameters)** will continue the numeric series.*

```
// Default Series
$serial = Earmarked::get(); // Returns: '2014'
$serial = Earmarked::get(3); // Returns: [ '2015', '2016', '2017', ]

// Using Same Parameters Again
$earmark = new Earmark('ZULU', null, 10, 5000, null);
$earmark->get(); // Returns: 'ZULU0000005004'
$earmark->get(3); // Returns: [ 'ZULU0000005005', 'ZULU0000005006', 'ZULU0000005007', ]
```

How it works
------------

[](#how-it-works)

Searching for gaps in a numerical series of numbers can be resource intensive. *Depends on the size of the series.*

This package uses two (`2`) tables, one for the series of used numbers and one to `Hold` a group of available numbers for immediate use. The package will `get()` the next consecutive number from the `Hold` table.

When the available numbers in the `Hold` table falls below one-third, this package will repopulate the `Hold` with more numbers. *This package works best with Laravel queues.*

Numbers in a series that have been `unset()` will be added to the `Hold` table for *reuse* when updated. *Numbers in the `Hold` table **are not** sorted, `unset()` numbers will **eventually** be available again.*

Additional Feature
------------------

[](#additional-feature)

### Auto-Increment

[](#auto-increment)

*Sometimes* you just want the next number in an auto-increment series. One is included in this package. It *does not* support `prefix`, *will not* support `suffix`, but you **can** use zero-padding.

**Do not use `unset()` with `increment()` values! You have been warned!**

```
Earmarked::increment(); // Returns: 1
Earmarked::increment(); // Returns: 2
$earmark = new Earmark('ZULU', null, 20, 5000, null);
$earmark->increment(true); // Returns: '00000000000000000003'
```

Contributing
------------

[](#contributing)

Thinking of contributing?

1. Fork &amp; clone the project: `git clone git@github.com:your-username/earmark.git`.
2. Run the tests and make sure that they pass with your setup: `phpunit`.
3. Create your bugfix/feature branch and code away your changes. Add tests for your changes.
4. Make sure all the tests still pass: `phpunit`.
5. Push to your fork and submit new a pull request.

###  Health Score

42

—

FairBetter than 90% of packages

Maintenance33

Infrequent updates — may be unmaintained

Popularity38

Limited adoption so far

Community13

Small or concentrated contributor base

Maturity68

Established project with proven stability

 Bus Factor1

Top contributor holds 96% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~86 days

Recently: every ~343 days

Total

23

Last Release

654d ago

PHP version history (3 changes)0.1.0PHP ^7

0.1.0.x-devPHP &gt;=7.2

0.2.1.x-devPHP &gt;=8.1

### Community

Maintainers

![](https://www.gravatar.com/avatar/cf9e48d0cc39504a157d0ac0d80caf504689caa71c81f9a0504da1999a9c5e25?d=identicon)[poing](/maintainers/poing)

---

Top Contributors

[![poing](https://avatars.githubusercontent.com/u/11417007?v=4)](https://github.com/poing "poing (72 commits)")[![StyleCIBot](https://avatars.githubusercontent.com/u/11048387?v=4)](https://github.com/StyleCIBot "StyleCIBot (2 commits)")[![dallincoons](https://avatars.githubusercontent.com/u/6494464?v=4)](https://github.com/dallincoons "dallincoons (1 commits)")

---

Tags

laraveleloquentprefixextensionvaluesuniquesequentialautoincrementincrementsuffixserialfollowingseriesserial numberauto-incrementconsecutivecontinualcontinuedcontinuingensuingextension numbergoing onsequentsequential valuessuccedentsucceedingsuccessionalsuccessivezero fillzerofill

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/poing-earmark/health.svg)

```
[![Health](https://phpackages.com/badges/poing-earmark/health.svg)](https://phpackages.com/packages/poing-earmark)
```

###  Alternatives

[tucker-eric/eloquentfilter

An Eloquent way to filter Eloquent Models

1.8k4.8M26](/packages/tucker-eric-eloquentfilter)[owen-it/laravel-auditing

Audit changes of your Eloquent models in Laravel

3.4k33.0M95](/packages/owen-it-laravel-auditing)[mongodb/laravel-mongodb

A MongoDB based Eloquent model and Query builder for Laravel

7.1k7.2M71](/packages/mongodb-laravel-mongodb)[watson/validating

Eloquent model validating trait.

9723.3M47](/packages/watson-validating)[cybercog/laravel-ban

Laravel Ban simplify blocking and banning Eloquent models.

1.1k651.8k11](/packages/cybercog-laravel-ban)[dyrynda/laravel-model-uuid

This package allows you to easily work with UUIDs in your Laravel models.

4802.8M8](/packages/dyrynda-laravel-model-uuid)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
