Coder Social home page Coder Social logo

forecaster's Introduction

Forecaster ⛅ Build Status

Forecaster is a library for manipulating and casting associative arrays in PHP.

While the project makes use of a class and helpers found in Laravel it can be used in non-Laravel projects as it only depends upon the Tighten Co's Collect package and not the Laravel Support package meaning it's compatible with any framework or stand-alone project.

Installation

Forecaster is compatible and tested with PHP 7.1 and greater.

This package should be installed through composer using the following command:

composer require ylsideas/forecaster

Usage

You can use Forecaster to process arrays with casting and array placement. For example all the following basic types are included, int, integer, float, double, real, string, boolean and bool. You can also ignore the data type argument so no casting is done but the key will still be included.

$result = forecast([
    'a-string-int' => '10',
    'a-string-float' => '1.5',
    'an-int' => 10,
    'another-int' => 1,
    'do-not-touch' => '11'
])
    ->cast('a-string-int', 'anInt', 'int')
    ->cast('a-string-float', 'aFloat', 'float')
    ->cast('an-int', 'aString', 'string')
    ->cast('another-int', 'aBoolean', 'bool')
    ->cast('do-not-touch', 'doNotTouch')
    ->get();

// $results to

[
    'anInt' => 10,
    'aFloat' => 1.5,
    'aString' => '10',
    'aBoolean' => true,
    'doNotTouch' => '11',
]   

Forecaster can also handle more complex array structures using dot notation.

$result = forecast([
    'onions' => [
        'have' => [
            'layers' => true,
        ]
    ]
])
    ->cast('onions.have.layers', 'ogres.do.to')
    ->get();
    
// results to

[
    'orgres' => [
        'do' => [
            'to' => true,
        ]
    ]
]               

A nice piece of functionality is that it can cast all the values of an array using the castAll method. There is even the option to do this using wild cards.

$result = forecast([
    'anArrayOfStrings' => [
        '10', '100', '1000'
    ],
    'anArrayOfArrays' => [
        ['value' => '20'],
        ['value' => '200'],
        ['value' => '2000'],
    ]
])
    ->castAll('anArrayOfStrings', 'an-array-of-ints')
    ->castAll('anArrayOfArrays.*.value', 'an-array-of-all-values')
    ->get();
    
// results to

[
    'an-array-of-ints' => [
        10, 100, 1000
    ],
    'an-array-of-all-values' => [
        20, 200, 2000
    ],
]               

You need not use just arrays, you may also use an object or a mix of objects and arrays with the same dot notation.

$object = new stdClass();
$object->objField = [
    'arrField' => '10',
];

$result = forecast($object)
    ->cast('objField.arrField', 'my_field', 'int')
    ->get();
    
// results to

[
    'my_field' => 10,
]               

Manipulating sub arrays is also relatively easy using the castItems method

$result = forecast([
    'an-array' => [
        ['attr' => '10'],
        ['attr' => '100'],
        ['attr' => '1000'],
    ]
])
    ->castItems('an-array', 'anArray', function (Forecaster $forecaster) {
        $forecaster->cast('attr', 'Attribute', 'int');
    })
    ->get();
    
// results to

[
    'anArray' => [
        ['Attribute' => 10],
        ['Attribute' => 100],
        ['Attribute' => 1000],
    ]
]    

Add your own fixed transformers

You can apply your own transformers to the Forecaster class statically making them available to all instances created.

Forecaster::transformer('csv', function ($value) {
    return str_getcsv($value);
});

$results = forecast([
    'test' => '1, 2, 3',
])
    ->cast('test', 'output', 'csv')
    ->get();
    
// results to

[
    'output' => ['1', '2', '3']
]

Use functions for casting on the fly

$results = forecast([
    'test' => '1, 2, 3',
])
    ->cast('test', 'output', function ($value) {
        return str_getcsv($value);
    })
    ->get();
    
// results to

[
    'output' => ['1', '2', '3']
]

Use classes for more complex casting

You can define transformers if you need to perform more complex logic that you wish to reuse.

public class CsvTransformer implements CastingTransformer
{
    public function cast(string $in, string $out, array $item, array $processed)
    {
        return str_getcsv($item[$in]);
    }
}

Which can then be applied when using forecast.

$results = forecast([
    'test' => '1, 2, 3',
])
    ->cast('test', 'output', new CsvTransformer())
    ->get();
    
// results to

[
    'output' => ['1', '2', '3']
]

Conditional transformations

Sometimes you might want to only perform some casting based on certain conditions. Forecaster provides a function for this that will only execute when the condition is truthy (e.g. == true).

$processed = Forecaster::make([
    'test' => '10',
])
    ->when(true, function (Forecaster $caster) {
        $caster->cast('test', 'output', 'int');
    })
    ->get();
    
// results to

[
    'output' => 10, 
]    

You may also use a function to resolve the conditional.

$processed = Forecaster::make([
    'test' => '10',
])
    ->when(
        function ($item) {
            return $item['test'] > 1;
        }, 
        function (Forecaster $caster) {
            $caster->cast('test', 'output', 'int');
        }
    )
    ->get();
    
// results to

[
    'output' => 10, 
]    

Cast Into objects

If you're rather turn the result into an object of your choice you can provide a class string to the get method.

$results = forecast([
    'test' => '10',
])
    ->cast('test', 'output')
    ->get(SomeClass::class);

You can also provide the string object as a parameter which will instruct the forecaster instance to cast the array into a stdClass object.

$object = forecast([
    'test' => '10',
])
    ->cast('test', 'output')
    ->get('object');

There is also the option to resolve this using a function.

$results = forecast([
    'test' => '10',
])
    ->cast('test', 'output')
    ->get(function ($processed) {
        return new SomeClass($processed['output']);
    });

Using it with Laravel/Tighten Collections

If you have an array of items you'd like to cast that's already in a Laravel/Tighten Collection class a macro is available allowing you to do it seamlessly.

$collection = collect([
    ['test' => '123.456'],
    ['test' => '789.101112']
])
    ->forecast(function (Forecaster $forecast) {
        $forecast->cast('test', 'output', 'float');
    })
    ->toArray();
    
// results to

[
    ['output' => 123.456],
    ['output' => 789.101112],
]

This macro also lets you specify the outcome of the forecast if you want to transform each of them into a particular class or an stdObject.

$collection = collect([
    ['test' => '123.456'],
    ['test' => '789.101112']
])
    ->forecast(
        function (Forecaster $forecast) {
            $forecast->cast('test', 'output', 'float');
        }, 
        'object'
    );

FAQ

Why no datetime converter?

Currently we feel this should be implemented by the user and not apart of the library due to how some developers only use datetime while others would use additional packages like Carbon or Chronos. We're open to ideas for this as it makes sense. We just don't want to put forward something that requires a breaking change early on.

Testing

Testing for this package is done using PHPUnit. You can run this from the composer dependencies. Running vendor/bin/phpunit will execute phpunit.xml.dist but you may copy it to phpunit.xml if you wish to change it for your own testing but please do not commit your version of phpunit.xml as part of any PR.

Contributing

If you wish to contribute to this project, please read the included contribution guide

License

This project is covered by the MIT license and can be read about the included license.md.

forecaster's People

Contributors

peterfox avatar svenluijten avatar

Stargazers

André Philip avatar Javier Sánchez Baeza avatar Ümit KTK avatar Mustafa TOKER avatar Brian Faust avatar Yevgeniy Dymov avatar Ismail Zahee avatar  avatar Chun-Sheng, Li avatar Lee Millward avatar Pankaj avatar nwrman avatar Paul Grant Truesdell, II avatar Matthias Lotze avatar Burak Sormageç avatar Adnan RIHAN avatar Andrew Golubev avatar Yılmaz Demir avatar Cyril de Wit avatar Richard avatar  avatar Adrian Gordon avatar Krystian Duma avatar

Watchers

André Philip avatar  avatar

Forkers

peterfox

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.