collab-corp / formatter
Formatting utility package for php
Requires
- php: ^8.0
- illuminate/support: ~7.0|^8.0|^9.0
- illuminate/validation: ~7.0|^8.0|^9.0
Requires (Dev)
- phpunit/phpunit: ^9.3
- symfony/var-dumper: ^6.0
README
A php package for formatting data/values using a laravel validation like syntax, powered by Illuminate\Support
components.
Installation
composer require collab-corp/formatter
Use
The most basic use is simple, just pass your value and array of callables that your value should be called against:
use CollabCorp\Formatter\Support\ValueFormatter; $formatter = new ValueFormatter(" uncle bob ", ['trim', 'ucwords']); $formatter->apply()->get(); // returns "Uncle Bob"
Passing Arguments To Callables
You can specify arguments using a :
followed by a comma delimited list e.g callable:arg1,arg2
:
function suffix_string($value, $suffix) { return $value.$suffix; } $formatter = new ValueFormatter(" Foo ", ['trim', 'suffix_string:Bar']); $formatter->apply()->get(); // returns "FooBar"
Note: Notice that we only specified the suffix
parameter. The ValueFormatter
class
automatically passes your value as the first parameter to every function with the exception of
delegation to objects/instances (See Using Instances section below).
What if value isnt the first parameter to my function?
No problem, you can specify what order you want your value passed by using the :value:
placeholder:
For example, preg_replace
accepts a value to format as the third parameter:
// trim & replace all non numerics with "#" $formatter = new ValueFormatter(" ABC123 ", [ 'trim', 'preg_replace:/[^0-9]/,#,:value:' ]); $formatter->apply()->get(); // returns "###123"
Whitelisting Allowed Callables
By default, all callables are allowed to be called, but if you are dynamically calling callables or want to add a protection layer, it may be worth specifying what callable functions should be allowed:
$formatter = new ValueFormatter(" uncle bob ", ['trim', 'ucwords']); $formatter->allowedCallables(["trim"]); //only trim is allowed // throws InvalidArgumentException: // "Encountered non whitelisted function or non callable [ucwords]" $formatter->apply()->get();
Using Instances/Object Values & Method Chaining
It is possible to pass an object/instance to the formatter and utilize any methods
on that instance. Using a .<methodName>
convention you can specify method chaining on that
instance. For example take a Carbon instance:
$formatter = new ValueFormatter(new Carbon\Carbon('2020-05-24'), [ '.addDays:1', '.format:m/d/Y' ]); $formatter->apply()->get() // returns "05/25/2020"
Closures/Formattable Classes
You can use closures for formatting your value as well:
$formatter = new ValueFormatter("the value", [ function($value){ //do something to the value return $value; }, ... ]);
Or you can also implement the CollabCorp\Formatter\Support\Contracts\Formattable
contract and use instances:
use CollabCorp\Formatter\Support\Contracts\Formattable; use Closure; class FormatValue implements Formattable { /** * Format the value. * * @param mixed $value * @param Closure $exit * @return mixed */ public function format($value, Closure $exit) { // quit formatting value(s) if($someCondition){ $exit(); } // or change the $value $value = "Changed" return $value; } } $formatter = new ValueFormatter("The value", [ "trim" new FormatValue // or using class constant: FormatValue::class // formatter will new up the class. ]);
Optional Formatting/Blank Input
Sometimes you may only want to format a value if the value isnt null
or "blank":
You can specify ?
anywhere in the chain of callables to specify if the formatter
should break out of processing callables, often this should be defined in front of all
your callables:
$formatter = new ValueFormatter(null, [ "?", //tells the class not to process callables if value is blank 'to_carbon', '.addDays:1', '.format:m/d/Y' ]); $formatter->apply()->get(); // returns original null value
Note: This packages uses Laravel's blank helper to determine blank/empty values.
If you have more complicated logic to break out of rules, use a closure or a Formattable
class and call the 2nd argument exit
callback:
$formatter = new ValueFormatter(null, [ function($value, $exit){ if($quitProcessing){ $exit(); // tells formatter to quit processing. } }, 'to_carbon', '.addDays:1', '.format:m/d/Y' ]);
Formatting multiple values
So far all the examples have been using a single value, but often times we are working
with much more data from client requests. This is where the DataFormatter
class is preferred:
use CollabCorp\Formatter\DataFormatter; $data = [ 'first_name'=>' jim ', 'last_name'=>' thompson', 'phone_number'=>'123-456-7890', 'date_of_birth'=>"1991-05-01", ... ]; $callables = [ 'first_name'=>'trim|ucfirst', 'last_name'=>'trim|ucfirst', 'phone_number'=>'preg_replace:/[^0-9]/,,:value:', 'date_of_birth'=>'?|to_carbon|.format:m/d/y', ... ]; $formatter = new DataFormatter($data, $callables); $formatter->apply()->get(); //returns formatted data
Array Input
You may also format array data using dot notation:
$data = [ 'contact_info'=>[ 'first_name'=>' jim ', 'last_name'=>' thompson', 'phone_number'=>'123-456-7890', 'address'=>'123 some lane.' ] ]; $callables = [ 'contact_info.first_name'=>'trim|ucwords', 'contact_info.last_name'=>'trim|ucwords', 'contact_info.phone_number'=>'preg_replace:/[^0-9]/,,:value:', 'contact_info.address'=>[function ($address) { return 'Address Is: '.$address; }], ]; $formatter = new DataFormatter($data, $callables); $formatter->apply()->get();
Wildcard Formatting
Callables can contain wildcards as well:
$data = [ 'first_name'=>' jim ', 'last_name'=>' thompson', ... ]; $callables = [ //apply to all keys that contain "name" '*name*'=>'trim|ucwords', ]; $formatter = new DataFormatter($data, $callables); $formatter->apply()->get();
This includes array input:
$callables = [ 'contact_info.*name*'=>'trim|ucwords', // 'contact_info.*name'=>'trim|ucwords', // 'contact_info.name*'=>'trim|ucwords', ]; $formatter = new DataFormatter($data, $callables); $formatter->apply()->get();
Concerns
If you prefer using a trait to easily create formatter instances, we provide the CollabCorp\Formatter\Support\Concerns\FormatsData
trait for easy access:
<?php use CollabCorp\Formatter\Support\Concerns\FormatsData; class SomeClass { use FormatsData; public function someFunction() { //returns ValueFormatter $this->formatValue("...", [...])->apply()->get(); //returns DataFormatter $this->formatData([...], [...])->apply()->get(); } }
Contribute
Contributions are always welcome in the following manner:
- Issue Tracker
- Pull Requests
- Collab Corp Discord (Will send invite as requested)
License
The project is licensed under the MIT license.