Completed
Push — master ( f1fa31...9e001b )
by Delete
04:20
created

DataSetsFromContentTrait::getDataSetFromString()   B

Complexity

Conditions 4
Paths 5

Size

Total Lines 28
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 28
rs 8.5806
cc 4
eloc 15
nc 5
nop 1
1
<?php
2
declare(strict_types=1);
3
4
namespace Crossjoin\Browscap\Source\Ini;
5
6
use Crossjoin\Browscap\Exception\ParserRuntimeException;
7
use Crossjoin\Browscap\Exception\SourceUnavailableException;
8
use Crossjoin\Browscap\Source\DataSet;
9
10
/**
11
 * Trait DataSetsFromContentTrait
12
 *
13
 * @package Crossjoin\Browscap\Source\Ini
14
 * @author Christoph Ziegenberg <[email protected]>
15
 * @link https://github.com/crossjoin/browscap
16
 */
17
trait DataSetsFromContentTrait
18
{
19
    /**
20
     * To be overwritten and filled with content by the class using this trait!
21
     *
22
     * @return \Generator
23
     */
24
    public function getContent() : \Generator
25
    {
26
        yield '';
27
    }
28
29
    /**
30
     * @inheritdoc
31
     *
32
     * @throws ParserRuntimeException
33
     * @throws SourceUnavailableException
34
     */
35
    public function getDataSets() : \Iterator
36
    {
37
        $unprocessedBytes = '';
38
        foreach ($this->getContent() as $bytes) {
39
            $combinedBytes = $unprocessedBytes . $bytes;
40
            $patternStart = strpos($combinedBytes, '[');
41
            if ($patternStart !== false) {
42
                while (($nextPatternStart = strpos($combinedBytes, '[', $patternStart + 1)) !== false) {
43
                    $dataSet = substr($combinedBytes, $patternStart, $nextPatternStart - $patternStart);
44
                    yield $this->getDataSetFromString($dataSet);
45
                    $patternStart = $nextPatternStart;
46
                    $unprocessedBytes = substr($combinedBytes, $nextPatternStart);
47
                }
48
            } else {
49
                $unprocessedBytes = $combinedBytes;
50
            }
51
        }
52
        if (trim($unprocessedBytes) !== '') {
53
            yield $this->getDataSetFromString($unprocessedBytes);
54
        }
55
    }
56
57
    /**
58
     * @param string $data
59
     *
60
     * @return DataSet
61
     * @throws ParserRuntimeException
62
     */
63
    protected function getDataSetFromString(string $data) : DataSet
64
    {
65
        if (strpos($data, "\n") === false) {
66
            throw new ParserRuntimeException('The data could not be parsed (no pattern found).', 1459589758);
67
        }
68
69
        if (strpos($data, "\r\n") !== false) {
70
            // if the source file was created under windows, replace the line endings
71
            $data = str_replace("\r\n", "\n", $data);
72
        }
73
74
        // Prepare the data from the data set
75
        list($pattern, $properties) = explode("\n", $data, 2);
76
        $pattern = substr($pattern, 1, -1);
77
78
        $properties = @parse_ini_string($properties);
79
        if ($properties === false) {
80
            throw new ParserRuntimeException(
81
                "The data could not be parsed (invalid properties for pattern '$pattern').",
0 ignored issues
show
Coding Style Best Practice introduced by
As per coding-style, please use concatenation or sprintf for the variable $pattern instead of interpolation.

It is generally a best practice as it is often more readable to use concatenation instead of interpolation for variables inside strings.

// Instead of
$x = "foo $bar $baz";

// Better use either
$x = "foo " . $bar . " " . $baz;
$x = sprintf("foo %s %s", $bar, $baz);
Loading history...
82
                1459589759
83
            );
84
        }
85
86
        $dataSet = new DataSet($pattern);
87
        $dataSet->setProperties($properties);
88
89
        return $dataSet;
90
    }
91
}
92