Download the PHP package slash197/reges-laravel without Composer

On this page you can find all versions of the php package slash197/reges-laravel. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.

FAQ

After the download, you have to make one include require_once('vendor/autoload.php');. After that you have to import the classes with use statements.

Example:
If you use only one package a project is not needed. But if you use more then one package, without a project it is not possible to import the classes with use statements.

In general, it is recommended to use always a project to download your libraries. In an application normally there is more than one library needed.
Some PHP packages are not free to download and because of that hosted in private repositories. In this case some credentials are needed to access such packages. Please use the auth.json textarea to insert credentials, if a package is coming from a private repository. You can look here for more information.

  • Some hosting areas are not accessible by a terminal or SSH. Then it is not possible to use Composer.
  • To use Composer is sometimes complicated. Especially for beginners.
  • Composer needs much resources. Sometimes they are not available on a simple webspace.
  • If you are using private repositories you don't need to share your credentials. You can set up everything on our site and then you provide a simple download link to your team member.
  • Simplify your Composer build process. Use our own command line tool to download the vendor folder as binary. This makes your build process faster and you don't need to expose your credentials for private repositories.
Please rate this library. Is it a good library?

Informations about the package reges-laravel

reges-laravel

CI Latest version

Laravel bridge for slash197/reges, the PHP client for the REGES Online API, the Romanian general register of employees run by Inspecția Muncii.

Status: 0.x. Verified against the REGES test environment, but the API of this package may still change before 1.0. See the changelog.

Reporting to REGES is not a single HTTP call. A submission is only queued; the outcome arrives later in a separate queue; a contract's messages must arrive in order; and the id REGES gives a new employee is needed before the contract can be sent. This package takes care of that part for a Laravel application:

What stays in your application is what only it knows: turning your employees and contracts into messages, deciding which operation a change amounts to, and what to do when a message is accepted or refused. Building messages, the 42 operations and the rules of the registry are described in the core package's README; read it alongside this one.

Contents

Requirements

Laravel's queue is not used.

Installation

The service provider and the Reges facade are discovered automatically. The migration creates one table, reges_messages.

Publish the config file if you want to change more than the environment variables allow, and the migration if you want to alter it:

Quick start

For one company, on the REGES test environment.

1. Credentials. REGES uses two sets: an OAuth client id and secret, the same for every integrator (the ones for the test environment are published in the official integration docs), and an API key pair per employer registry, generated in the REGES employer application under Setări → Acces → Chei API.

2. Check the setup and download the nomenclators.

3. Schedule the commands, in routes/console.php:

4. Queue a message where your application registers an employee:

5. Handle the outcome in listeners:

Within a minute or two the employee is in the registry and your model has its REGES id.

Configuration

Everything is driven by environment variables; the published config/reges.php holds a few more settings.

Variable Default Meaning
REGES_ENVIRONMENT test test or production
REGES_CLIENT_ID, REGES_CLIENT_SECRET none OAuth client issued by REGES for your software
REGES_CLIENT_APPLICATION APP_NAME Name of your software, reported in every message header
REGES_CLIENT_VERSION 1.0 Version of your software
REGES_USER none Default name of the person on whose behalf messages are sent
REGES_USERNAME, REGES_PASSWORD none API key of the one registry, when there is only one
REGES_OUTBOX true Whether the package keeps the outbox table and sends from it
REGES_CONSUMER_ID none Consumer id the result queues are read as
REGES_CACHE_STORE default store Cache store that keeps the access tokens
REGES_NOMENCLATOR_CACHE_STORE REGES_CACHE_STORE Cache store that keeps the nomenclator copy
REGES_LOG_CHANNEL default channel Log channel that receives request metadata
REGES_API_URL, REGES_TOKEN_URL per environment Overrides for the API and token hosts
Config key Default Meaning
reges.outbox.table reges_messages Name of the outbox table; change it before migrating
reges.outbox.limit 100 Most messages reges:send attempts in one run
reges.outbox.retry_delay 60 Seconds between attempts after a transient failure
reges.outbox.give_up_after 259200 (3 days) Seconds after which an undelivered message is given up on; 0 never gives up
reges.outbox.sending_timeout 600 Seconds after which a message left mid-send by a dead process is sent again
reges.results.limit 500 Most results reges:results reads per registry in one run
reges.http.timeout, reges.http.connect_timeout 30, 10 Timeouts of the built-in HTTP client, in seconds
reges.tokens.prefix, reges.nomenclators.prefix reges:token:, reges:nomenclator: Cache key prefixes

Who is sending. REGES records two identities with each message. The author is the API key. The user is a free-text name of the person in your application: pass it per message (user:), or set REGES_USER as the default. A message with neither is refused before it is stored.

Production. Set REGES_ENVIRONMENT=production and the client id and secret REGES issued for production. The production token URL in the core package was derived by analogy with the test one; if authentication fails there, set REGES_TOKEN_URL.

One registry or several

An API key belongs to exactly one employer registry. The bridge refers to a registry by a registry key, a string your application chooses.

One registry

With REGES_USERNAME and REGES_PASSWORD set there is one registry, called default, and you never need to name it. The client is in the container and behind a facade:

Several registries

A SaaS, a payroll bureau or a group of companies has one API key per company. Tell the bridge where the keys are by binding a CredentialsProvider; the registry key is then whatever identifies a company to you, typically its id:

Leave REGES_USERNAME and REGES_PASSWORD empty. Throw from credentials() for a company that has no key or has REGES switched off: queue() then fails for that company, and messages it already has in the outbox stay pending and are retried, so they go out once the key is back.

Pass the registry key wherever the bridge takes one, and get a client for a registry directly when you need it:

Things worth knowing:

Sending messages

Queueing

Argument Purpose
$message A slash197\Reges\Message, built as the core README describes
sequence Messages sharing it are sent strictly in order; see below. null sends independently
registry The registry key; leave out with a single registry
subject The Eloquent model the message is about; you get it back with the outcome
meta An array of anything else you want back with the outcome
user The person on whose behalf the message is sent; falls back to REGES_USER

queue() validates the message, puts it in its final wire form and stores it. It makes no HTTP request, so it is safe to call inside a web request or a database transaction. It returns the stored message.

If the message lacks something its operation needs, or a value is not in the nomenclators, queue() throws and stores nothing:

Sequences

REGES processes messages in the order it receives them and refuses a contract's messages that arrive out of order. Messages queued with the same sequence are therefore sent one at a time, in the order they were queued, each waiting for the result of the one before.

Messages that depend on an earlier result

A contract needs the REGES id of its employee, and a change to a contract needs the REGES id of the contract. Those ids only exist once the earlier message has been accepted, so queue the dependent message from your MessageAccepted listener:

What ref identifies depends on the operation: the new employee, the new contract, the new proposal, or the history entry a contract operation created. The table is in the core README.

Sending

reges:send sends every message that is due, oldest first, and reges:results records the outcomes. Schedule both every minute, as in the quick start. On the test environment a result typically arrives within a second or two of sending, so a message is usually resolved on the run after the one that sent it.

A message goes through these statuses:

Status Meaning
pending Waiting to be sent, for the first time or again after a transient failure
sending Being sent right now
sent Queued by REGES; its result has not arrived yet
accepted REGES carried the operation out
rejected REGES refused it, on submission or in its result
failed It could not be delivered before the retry window closed
cancelled Withdrawn by your application before it was sent

Retries and failures

What happens What the outbox does
No response, a 5xx, 408 or 429 Back to pending; retried after retry_delay, which doubles after the 60th attempt up to 12 hours
Credentials refused, unknown registry, or any other error while sending The same, and the exception is reported to your exception handler
REGES refuses the submission (any other 4xx, typically a 400 with schema problems) rejected, MessageRejected is dispatched; not retried
REGES accepts the submission, then reports a failure in its result rejected, MessageRejected is dispatched
Still undelivered give_up_after seconds after it was queued failed, MessageFailed is dispatched
The process dies mid-send Sent again after sending_timeout, with the same message id, because whether REGES received it is unknown

To send something again after a rejection, fix the data and queue a new message. A stored message is never rebuilt, since its timestamp and content are final.

The stored message

queue() returns a slash197\Reges\Laravel\Outbox\OutboxMessage, an Eloquent model, and the events carry the same model.

Attribute Meaning
id Auto-incrementing; the order within a sequence
registry The registry key
message_id The id REGES matches the result by
operation The operation name, e.g. AdaugareContract
sequence The sequence it was queued in, if any
subject The model you passed, as a morphTo relation (subject_type, subject_id)
meta The array you passed
status A MessageStatus enum case
payload The message as sent, JSON; envelope() returns it as an Envelope
attempts, last_attempt_at, next_attempt_at Delivery bookkeeping
sent_at, resolved_at When REGES queued it, and when its outcome was recorded
response_id The id REGES gave the submission
ref, sec_ref The ids REGES returned with the result
result_code, result_description The outcome as REGES words it
error Why the last attempt failed or why the message was refused

Give your own models the inverse relation to show the REGES state of a record:

A message that has not been sent yet can be withdrawn; cancel() returns false once it is too late:

Old messages are not pruned. Delete what you no longer need yourself, keeping in mind that the ref of an accepted message is the only record of that id unless you copied it to your own tables.

Reading results

reges:results reads the result queue of the configured registry and of every registry that has a message awaiting its result. For each result it dispatches a ResultReceived event; the outbox listens to it, matches the result to its stored message and dispatches MessageAccepted or MessageRejected.

You only need ResultReceived yourself to see every result, including those of messages your application did not send through the outbox:

Nothing is lost, and listeners may run twice. The queue moves past a result only after every listener has returned, including your MessageAccepted and MessageRejected listeners. If one throws, that registry's run stops, the exception is reported, and the same result is delivered again on the next run. Two consequences:

A listener that implements ShouldQueue counts as done once it is on your queue.

Sharing a registry. Each reader of a registry's queue has its own position, identified by a consumer id. If another application, or another environment of yours, reads the same registry, give each its own REGES_CONSUMER_ID, or they take each other's results. A new consumer id starts from the beginning of the queue.

Options. --registry=KEY (repeatable) reads only the registries named, --consumer=ID overrides the consumer id, and --limit=N caps the results read per registry in one run.

Your own loop. ResultReader is what the command uses, if you want to read a queue from your own code:

Nomenclators

The nomenclators are the reference lists REGES validates against. With a local copy, the client checks three kinds of value before a message is stored or sent: country names, identity document types and locality (SIRUTA) codes.

Countries are referred to by name, spelled exactly as the nomenclator spells it (România, not Romania); most other fields take a code. To fill your own dropdowns, fetch any list through the client: Reges::nomenclators()->get('TemeiIncetare').

Commands

Command What it does
reges:check Read-only check of the configured registry: authentication, the employer profile, a look at the result queue without advancing it, and whether a nomenclator copy exists
reges:send Sends the stored messages that are due. --limit=N caps the attempts in one run
reges:results Reads the result queues and dispatches the events. --registry=KEY, --consumer=ID, --limit=N
reges:nomenclators Downloads the nomenclators

reges:send is registered only while the outbox is enabled. reges:results exits with a failure code if any registry could not be read, after reading the others.

Events

All in slash197\Reges\Laravel\Events.

Event Properties When
MessageAccepted message, result REGES carried the operation out. $message->ref is the id of what it created
MessageRejected message, result (null when refused on submission) REGES refused the message. $message->error says why
MessageFailed message The message could not be delivered within the retry window. $message->error holds the last failure
ResultReceived result, registry Any result was read from a registry's queue

Without the outbox

If your application already has its own way of storing and ordering messages, set REGES_OUTBOX=false. No table is created and reges:send is not registered. You still get the configured client, the registries, token caching, the nomenclator copy, reges:check and reges:results:

and match results in a ResultReceived listener by $event->result->messageId. With the outbox off, reges:results reads the configured registry, or the ones you name with --registry.

You can also mix the two: a message sent directly through the client simply has no stored counterpart, and its result reaches you through ResultReceived only.

Tokens, HTTP client and logging

Tokens. Access tokens are kept in the cache, encrypted with the application key, until they expire. To keep them elsewhere, implement slash197\Reges\Auth\TokenStore and bind it:

To build a single client with a store of its own, outside the registries, use the factory: app(RegesFactory::class)->make($credentials, $tokenStore).

HTTP client. Requests go through a Guzzle client with the timeouts from reges.http. If your application binds Psr\Http\Client\ClientInterface in the container, that client is used instead, and timeouts, proxies and retries are yours to configure on it.

Logging. The client logs one line per request to REGES_LOG_CHANNEL: method, endpoint, status and the request id REGES returns. Message contents are never logged.

Personal data

Messages to REGES carry CNPs, names and addresses, and so do its answers (a result reads, for example, "Salariatul … cu CNP … a fost adăugat cu succes"). The package therefore:

Rotating APP_KEY makes stored messages unreadable unless you keep the old key in APP_PREVIOUS_KEYS. meta is stored as plain JSON, so do not put personal data in it. The exception messages the commands print and report can quote what REGES answered.

Testing your application

Outbox::queue() makes no HTTP request, and an outcome can be simulated by dispatching the result yourself, so most tests need no fake client at all.

Give the test environment an API username that is a UUID, because REGES identifies the author by it and the message is validated accordingly:

Assert that your code queued the right message:

Simulate the outcome and assert what your listeners did:

Any code other than SUCCES, with a description, simulates a rejection.

To exercise the HTTP layer as well, bind a fake PSR-18 client before anything resolves the REGES client, for example in setUp():

A mock that has run out of responses throws, which also guarantees that a test never reaches the real REGES.

Troubleshooting

Symptom Likely cause
reges:check says the credentials are missing REGES_USERNAME and REGES_PASSWORD are empty. With several registries that is expected: reges:check covers the configured registry only
Authentication fails Wrong client id or secret for the environment, or an API key from the other environment. Test and production keys are separate
Unknown REGES registry "…" A registry key was used but no CredentialsProvider is bound, so only default exists
Messages stay pending The scheduler is not running; or an earlier message of the same sequence is still unresolved; or sending keeps failing, in which case error says why
Messages stay sent reges:results is not running; or another application reads the same registry with the same consumer id and takes the results
A message is rejected with a schema error REGES refused the submission. error holds its answer; the core README's list of what REGES is strict about usually explains it
A later contract message is rejected as out of order Messages for one contract were queued in different sequences, or queued in a different order than the changes happened
Values that are not in the nomenclators get through There is no local copy; run reges:nomenclators (it is lost on cache:clear)
queue() says REGES needs the name of the user Pass user: or set REGES_USER
The migration fails because reges_messages exists Your application has a table of that name; set reges.outbox.table before migrating
Dates land a day early in the registry Build calendar days with Dates::date(), as the core README explains

Contributing

Issues and pull requests are welcome, including small ones: a bug report with the operation and what REGES answered is already useful. Please leave real CNPs, company codes and credentials out of issues, tests and commits.

Before opening a pull request, run make check. Tests must not reach the network; the test base class installs a fake HTTP client for that reason.

Questions about messages, operations and how REGES itself behaves belong in the core package.

Development

Nothing needs to be installed on the host besides Docker:

PHP_VERSION=8.4 make build switches the PHP version of the container.

Disclaimer

This is an independent, unofficial project. It is not affiliated with or endorsed by Inspecția Muncii. The official integration documentation lives at reges-ro/integrare.

Licence

MIT. See LICENSE.


All versions of reges-laravel with dependencies

PHP Build Version
Package Version
Requires php Version ^8.2
guzzlehttp/guzzle Version ^7.8
illuminate/console Version ^12.0 || ^13.0
illuminate/contracts Version ^12.0 || ^13.0
illuminate/database Version ^12.0 || ^13.0
illuminate/log Version ^12.0 || ^13.0
illuminate/support Version ^12.0 || ^13.0
psr/http-client Version ^1.0
psr/log Version ^2.0 || ^3.0
slash197/reges Version ^0.1
Composer command for our command line client (download client) This client runs in each environment. You don't need a specific PHP version etc. The first 20 API calls are free. Standard composer command

The package slash197/reges-laravel contains the following files

Loading the files please wait ...