Helpers
Helper classes dependency for Laravel Enso.
This package can work independently of the Enso ecosystem.
For live examples and demos, you may visit laravel-enso.com
Installation
Comes pre-installed in Enso.
To install outside of Enso: composer require laravel-enso/helpers
Usage
The following contracts, classes, exceptions and traits are available.
Contracts
Activatable, makes sense for models that have anis_activecolumn demands the implementation of the following methods:isActive(): boolisInactive(): bool
Can be used together with the
ActiveStatetrait that provides a default implementation of the trait and more. For information on the trait, see below.
Classes
- A
Decimalsclass which is a wrapper for PHP'sbc*methods such asbcaddwith support for a customizable, default precision - A
JsonParserclass that takes a JSON file as its constructor's argument, and can parse and transform the file to:- object
- array
- JSON string
- An
Objclass which extends the Laravel Collection, with a constructor for building an object from an array, an object, a Laravel model that can even have loaded relationships and more. You can then use all the native Collection functions, as well as:set($key, $value),filled($key),
Decimals - LaravelEnso\Helpers\app\Classes\Decimals
All the class' methods are static.
Methods:
scale($precision), sets the default precision. If not specified, the precision will be2add($first, $second, $precision = null), callsbcaddwith the given/default precisionsub($first, $second, $precision = null), callsbcsubwith the given/default precisionmul($first, $second, $precision = null), callsbcmulwith the given/default precisiondiv($first, $second, $precision = null), callsbcdivwith the given/default precisionsqrt($first, $second, $precision = null), callsbcsqrtwith the given/default precisionpow($first, $second, $precision = null), callsbcpowwith the given/default precisionmod($first, $second, $precision = null), callsbcmodwith the given/default precisionpowmod($first, $second, $precision = null), callsbcpowmodwith the given/default precisionlt($first, $second, $precision = null), usesbccompwith the given/default precision, returns the boolean result of a less than comparisonlte($first, $second, $precision = null), usesbccompwith the given/default precision, returns the boolean result of a less or equals than comparisoneq($first, $second, $precision = null), usesbccompwith the given/default precision, returns the boolean result of an equals comparisonnotEq($first, $second, $precision = null), usesbccompwith the given/default precision, returns the boolean result of not equals comparisongt($first, $second, $precision = null), usesbccompwith the given/default precision, returns the boolean result of a greater than comparisongte($first, $second, $precision = null), usesbccompwith the given/default precision, returns the boolean result of a greater than or equals comparisonceil($first, $second, $precision = null), usesbcceilwith the given/default precision, returns the boolean result of a less than comparisonfloor($first, $second, $precision = null), usesfloorwith the given/default precision, returns the boolean result of a less than comparison
JsonParser - LaravelEnso\Helpers\app\Classes\JsonParser
The constructor takes a file name. This must be a text file with valid json content.
Note: When trying to read it, a JsonParseException exception will be thrown if the file contents is not valid.
Methods:
object(), returns an object representation of the filearray(), returns an array representation of the filejson, returns an json representation of the file
Obj - LaravelEnso\Helpers\app\Classes\Obj
The constructor optionally takes an associate array or an object (even a Laravel model). This parameter is used to set up the object. For arrays, it uses the array keys as properties and the array values as the property values.
Methods:
all,set(key, value), sets the value of the object's 'key' propertyfilled(key), returns true if the 'key' property exists on the object and its value is not null
For the list of available Collection methods, you may check out the official Laravel docs here.
Exceptions
A generic exception:
EnsoExceptionis available also with a Facade. This exception is extended by all the other Enso specific exceptions and it is not reported by the Laravel's Exception Handler.A
FileMissingException, a child ofEnsoExceptionA
JsonParseException, a child ofEnsoException
These exceptions are used throughout various Enso packages.
Traits
ActiveState
Adds the following methods for models that have a boolean is_active property:
whereActive()scopescopeInactive()scopeisActive()helperisInactive()helperactivate(), updates the model and sets is_active totruedeactivate(), updates the model and sets is_active tofalse
AvoidsDeletionConflicts
The trait is meant to provide a generic user readable message when trying to delete a model that cannot be actually deleted due to foreign key constraints.
It achieves this by overwriting the model's delete method, calls the parent delete method within a try-catch block
and if there is any QueryException, throws a ConflictHttpException letting the user know
the model is used and cannot be deleted.
CascadesMorphMap
The trait cascades Laravel's getMorphClass() method available on models and attempts to use
a key (if defined), otherwise falling back to the default Laravel implementation
SeederProgress
Allows to show a progress bar for long running database seeding processes.
To use it:
- import the trait
- declare a constant chunk with a value that makes sense
- before starting the seed process, call the trait's
start($count)method with the total count of the items that will be seeded - start the seeding process, while ensuring you're seeding using chunks, and after
completing each chunk, call the trait's
advance()method. - once the seeding is complete, call the trait's
end()method.
Example:
class ProductSeeder extends Seeder
{
use SeederProgress;
private const Chunk = 800;
public function run()
{
$this->chunk(self::Chunk)
->start(LegacyProduct::count());
LegacyProduct::chunkById(self::Chunk, function ($products) {
$this->insert($products);
$this->advance();
});
$this->end();
}
private function insert($products) { ... }
}
InCents
When working with monetary values, the trait is meant to make your life easier if you choose to store these values in cents.
To use the trait:
- add it to your class
- declare the
protected $centAttributes = [ ];field and set the model's monetary/cent attribute names - use the
inCents($mode)to convert your values from/to cents
For example:
- when returning a model to the front-end, after retrieving the it from the DB, call the
inCents(false)method of the trait which will convert the monetary values from cents to your currency - when creating a new model, before filling any monetary attributes, you should call the
inCents(true/false)method to set the appropriate mode for the values you'll be filling
The trait does a few things automatically, based on an internal $inCents flag/mode:
- whenever the model is retrieved from the DB, it notes that the values are in cents
- before saving the model:
- if the values are not in cents, it converts them to cents
- if the values are in cents, nothing is altered
- if it can't determine whether the values are in cents or not, a
LogicExceptionis thrown
- when calling the
inCentsmethod on a model with dirty monetary attributes, and its internal flag is not set, aLogicExceptionis thrown
The trait's internal $inCents flag is public, thus for situations where it makes sense,
you can set it directly, thus bypassing the inCents() method;
MapsRequestKeys
When working with Resource representations of models, you may choose to use camelCase representations for their attributes. Whenever updating the models based on user input, you'll probably want to fill the updated values, however you'll have to remap them due to the mismatching keys.
The trait can be used for FormRequest validations so that whenever the validation passes, you can update the model using:
$model->update($request->mapped());
UpdatesOnTouch
The trait can be used on models where, whenever updated, you might also want to touch other related (or parent) models.
To use it:
- add the trait to your model
- declare the
protected $touches = ['relation'];attribute and set the relationships to the related - within your logic, use the trait's
touchOwners
If any of the related models also use the UpdatesOnTouch trait, the touch will be cascaded.
Contributions
are welcome. Pull requests are great, but issues are good too.
License
This package is released under the MIT license.