Passed
Pull Request — master (#7)
by
unknown
02:07
created

CSVParser::getCurrentLineAsCollection()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 3
nc 1
nop 0
dl 0
loc 6
ccs 4
cts 4
cp 1
crap 1
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * Created by PhpStorm.
4
 * User: sergio.rodenas
5
 * Date: 15/5/18
6
 * Time: 18:59
7
 */
8
9
namespace Rodenastyle\StreamParser\Parsers;
10
11
12
use Rodenastyle\StreamParser\Exceptions\IncompleteParseException;
13
use Rodenastyle\StreamParser\StreamParserInterface;
14
use Tightenco\Collect\Support\Collection;
15
16
class CSVParser implements StreamParserInterface
17
{
18
	protected $reader, $source, $headers, $currentLine;
19
20
	public static $delimiters = [",", ";"];
21
22
	public static $allowEmptyString = false;
23
24
	public function __construct()
25
	{
26
		Collection::macro('recursive', function () {
27 4
			return $this->map(function ($value) {
0 ignored issues
show
Bug introduced by
The method map() does not exist on Rodenastyle\StreamParser\Parsers\CSVParser. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

27
			return $this->/** @scrutinizer ignore-call */ map(function ($value) {

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
28 4
				if (is_array($value) || is_object($value)) {
29 4
					return (new Collection($value))->recursive();
30
				}
31 4
				return $value;
32 4
			});
33 4
		});
34 4
	}
35
36 4
	public function from(String $source): StreamParserInterface
37
	{
38 4
		$this->source = $source;
39
40 4
		return $this;
41
	}
42
43 4
	public function each(callable $function)
44
	{
45 4
		$this->start();
46 4
		while($this->read()){
47 4
			$function($this->getCurrentLineAsCollection());
48
		}
49 4
		$this->close();
50 4
	}
51
52 4
	private function start()
53
	{
54 4
		$this->reader = fopen($this->source, 'r');
55
56 4
		$this->read();
57 4
		$this->headers = new Collection($this->currentLine);
58
59 4
		return $this;
60
	}
61
62 4
	private function close(){
63 4
		if( ! fclose($this->reader)){
64
			throw new IncompleteParseException();
65
		}
66 4
	}
67
68 4
	private function read(): bool{
69
		do {
70 4
			$line = fgetcsv($this->reader);
71
72 4
			$this->currentLine = (new Collection($line))->filter(function($value) {
73 4
				if(!self::$allowEmptyString && $value === '') {
74 4
					return false;
75
				}
76
77 4
				return $value !== null && $value !== false;
78 4
			});
79
80 4
			if($this->currentLine->isNotEmpty()) {
81 4
				return true;
82
			}
83 4
		} while($line !== null && $line !== false);
84
85 4
		return false;
86
	}
87
88 4
	private function getCurrentLineAsCollection()
89
	{
90 4
		$headers = $this->headers;
91 4
		$values = $this->formatCurrentLineValues($this->currentLine);
92
93 4
		return $headers->intersectByKeys($this->currentLine)->combine($values->recursive());
94
	}
95
96 4
	private function formatCurrentLineValues(Collection $collection){
97 4
		$this->explodeCollectionValues($collection);
98 4
		return $collection;
99
	}
100
101
	private function explodeCollectionValues(Collection $collection){
102
		$collection->transform(function($value){
103 4
			(new Collection(static::$delimiters))->each(function($delimiter) use (&$value){
104 4
				if( ! is_array($value) && strpos($value, $delimiter) !== false){
105 4
					$value = explode($delimiter, $value);
106
				}
107 4
			});
108 4
			if(is_array($value)){
109 4
				return (new Collection($value))->reject(function($value){
110 4
					return $value === null || $value === false || $value === '';
111 4
				});
112
			} else {
113 4
				return $value;
114
			}
115 4
		});
116 4
	}
117
}
118