Completed
Push — master ( 5c1aea...9ef1c4 )
by Luke
03:03
created

functions.php ➔ streamize()   D

Complexity

Conditions 10
Paths 10

Size

Total Lines 37
Code Lines 22

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 24
CRAP Score 10

Importance

Changes 0
Metric Value
cc 10
eloc 22
nc 10
nop 1
dl 0
loc 37
ccs 24
cts 24
cp 1
crap 10
rs 4.8196
c 0
b 0
f 0

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/**
3
 * CSVelte: Slender, elegant CSV for PHP
4
 *
5
 * Inspired by Python's CSV module and Frictionless Data and the W3C's CSV
6
 * standardization efforts, CSVelte was written in an effort to take all the
7
 * suck out of working with CSV.
8
 *
9
 * @version   v0.2.1
10
 * @copyright Copyright (c) 2016 Luke Visinoni <[email protected]>
11
 * @author    Luke Visinoni <[email protected]>
12
 * @license   https://github.com/deni-zen/csvelte/blob/master/LICENSE The MIT License (MIT)
13
 */
14
namespace CSVelte;
15
16
/**
17
 * Library Functions
18
 *
19
 * @package CSVelte
20
 * @subpackage functions
21
 * @since v0.2.1
22
 */
23
24
use \Iterator;
25
use CSVelte\IO\Stream;
26
use CSVelte\IO\Resource;
27
use CSVelte\IO\IteratorStream;
28
use CSVelte\Contract\Streamable;
29
30
use \InvalidArgumentException;
31
32
/**
33
 * Stream - streams various types of values and objects.
34
 *
35
 * You can pass a string, or an iterator, or an object with a __toString()
36
 * method to this function and it will find the best possible way to stream the
37
 * data from that object.
38
 *
39
 * @param mixed $obj The item you want to stream
40
 * @return Streamable
41
 * @throws InvalidArgumentException
42
 * @since v0.2.1
43
 */
44
function streamize($obj = '')
45
{
46 27
    if ($obj instanceof Streamable) {
47 1
        return $obj;
48
    }
49
50 27
    if ($obj instanceof Resource) {
51 1
        return $obj();
52
    }
53
54 26
    if (is_resource($obj) && get_resource_type($obj) == 'stream') {
55 1
        return new Stream(new Resource($obj));
56
    }
57
58 25
    if ($obj instanceof Iterator) {
59 4
        return new IteratorStream($obj);
60
    }
61
62 21
    if (is_object($obj) && method_exists($obj, '__toString')) {
63 2
        $obj = (string) $obj;
64 2
    }
65 21
    if (is_string($obj)) {
66 19
        $stream = Stream::open('php://temp', 'r+');
67 19
        if ($obj !== '') {
68 16
            $res = $stream->getResource();
69 16
            fwrite($res->getHandle(), $obj);
70 16
            fseek($res->getHandle(), 0);
71 16
        }
72 19
        return $stream;
73
    }
74
75 2
    throw new InvalidArgumentException(sprintf(
76 2
        "Invalid argument type for %s: %s",
77 2
        __FUNCTION__,
78 2
        gettype($obj)
79 2
    ));
80
}
81
82
/**
83
 * Stream resource factory.
84
 *
85
 * This method is just a shortcut to create a stream resource object using
86
 * a stream URI string.
87
 *
88
 * @param string $uri A stream URI
89
 * @param string $mode The access mode string
90
 * @param array|resource $context An array or resource with stream context options
91
 * @param bool $lazy Whether to lazy-open
92
 * @return $this
93
 * @since v0.2.1
94
 */
95
function stream_resource(
96
    $uri,
97
    $mode = null,
98
    $context = null,
99
    $lazy = true
100
) {
101 5
    $res = (new Resource($uri, $mode, null, true))
102 5
        ->setContextResource($context);
0 ignored issues
show
Bug introduced by
It seems like $context defined by parameter $context on line 98 can also be of type array; however, CSVelte\IO\Resource::setContextResource() does only seem to accept resource|null, maybe add an additional type check?

This check looks at variables that have been passed in as parameters and are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
103 5
    if (!$lazy) {
104 1
        $res->connect();
105 1
    }
106 5
    return $res;
107
}
108
109
/**
110
 * Stream factory.
111
 *
112
 * This method is just a shortcut to create a stream object using a URI.
113
 *
114
 * @param string $uri A stream URI to open
115
 * @param string $mode The access mode string
116
 * @param array|resource $context An array or stream context resource of options
117
 * @param bool $lazy Whether to lazy-open
118
 * @return Stream
119
 * @since v0.2.1
120
 */
121
function stream(
122
    $uri,
123
    $mode = null,
124
    $context = null,
125
    $lazy = true
126
) {
127 3
    $res = stream_resource($uri, $mode, $context, $lazy);
128 3
    return $res();
129
}
130
131
/**
132
 * "Taste" a stream object.
133
 *
134
 * Pass any class that implements the "Streamable" interface to this function
135
 * to auto-detect "flavor" (formatting attributes).
136
 *
137
 * @param Contract\Streamable Any streamable class to analyze
138
 * @return Flavor A flavor representing stream's formatting attributes
139
 * @since v0.2.1
140
 */
141
function taste(Streamable $str)
142
{
143 13
    $taster = new Taster($str);
144 13
    return $taster();
145
}
146
147
/**
148
 * Does dataset being streamed by $str have a header row?
149
 *
150
 * @param Contract\Streamable $str Stream object
151
 * @return boolean Whether stream dataset has header
152
 * @since v0.2.1
153
 */
154
function taste_has_header(Streamable $str)
155
{
156 5
    $taster = new Taster($str);
157 5
    $flv = $taster();
158 5
    return $taster->lickHeader(
159 5
        $flv->delimiter,
160 5
        $flv->lineTerminator
161 5
    );
162
}
163
164
/**
165
 * Collection factory.
166
 *
167
 * Simply an alias to (new Collection($in)). Allows for a little more concise and
168
 * simpler instantiation of a collection. Also I plan to eventually support
169
 * additional input types that will make this function more flexible and forgiving
170
 * than simply instantiating a Collection object, but for now the two are identical.
171
 *
172
 * @param array|Iterator $in Either an array or an iterator of data
173
 * @return Collection A collection object containing data from $in
174
 * @since v0.2.1
175
 * @see Collection::__construct() (alias)
176
 */
177
function collect($in = null)
178
{
179 65
    return new Collection($in);
180
}
181
182
/**
183
 * Invoke a callable and return result.
184
 *
185
 * Pass in a callable followed by whatever arguments you want passed to
186
 * it and this function will invoke it with your arguments and return
187
 * the result.
188
 *
189
 * @param callable $callback The callback function to invoke
190
 * @param array ...$args The args to pass to your callable
191
 * @return mixed The result of your invoked callable
192
 * @since v0.2.1
193
 */
194
function invoke(Callable $callback, ...$args)
195
{
196
    return $callback(...$args);
197
}