A php package for formatting data/values using a laravel validation like syntax, powered by Illuminate\Support
components.
composer require collab-corp/formatter
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"
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).
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"
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();
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"
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.
]);
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'
]);
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
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();
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();
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();
}
}
Contributions are always welcome in the following manner:
- Issue Tracker
- Pull Requests
- Collab Corp Discord (Will send invite as requested)
The project is licensed under the MIT license.