Passed
Push — master ( d7dee9...483d68 )
by Jan
04:53 queued 10s
created

ParameterExtractor   A

Complexity

Total Complexity 9

Size/Duplication

Total Lines 69
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 30
c 1
b 0
f 0
dl 0
loc 69
rs 10
wmc 9

3 Methods

Rating   Name   Duplication   Size   Complexity  
A stringToParam() 0 26 4
A extractParameters() 0 21 4
A splitString() 0 5 1
1
<?php
2
/**
3
 * This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
4
 *
5
 * Copyright (C) 2019 - 2020 Jan Böhmer (https://github.com/jbtronics)
6
 *
7
 * This program is free software: you can redistribute it and/or modify
8
 * it under the terms of the GNU Affero General Public License as published
9
 * by the Free Software Foundation, either version 3 of the License, or
10
 * (at your option) any later version.
11
 *
12
 * This program is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 * GNU Affero General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU Affero General Public License
18
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
19
 */
20
21
namespace App\Services\Parameters;
22
23
24
use App\Entity\Parameters\AbstractParameter;
25
use App\Entity\Parameters\PartParameter;
26
27
class ParameterExtractor
28
{
29
    protected const ALLOWED_PARAM_SEPARATORS = [", ", "\n"];
30
31
    protected const CHAR_LIMIT = 1000;
32
33
    /**
34
     * Tries to extract parameters from the given string.
35
     * Useful for extraction from part description and comment.
36
     * @param  string  $input
37
     * @param string $class
38
     * @return AbstractParameter[]
39
     */
40
    public function extractParameters(string $input, string $class = PartParameter::class): array
41
    {
42
        if (!is_a($class, AbstractParameter::class, true)) {
43
            throw new \InvalidArgumentException('$class must be a child class of AbstractParameter!');
44
        }
45
46
        //Restrict search length
47
        $input = mb_strimwidth($input,0,self::CHAR_LIMIT);
48
49
        $parameters = [];
50
51
        //Try to split the input string into different sub strings each containing a single parameter
52
        $split = $this->splitString($input);
53
        foreach ($split as $param_string) {
54
            $tmp = $this->stringToParam($param_string, $class);
55
            if ($tmp !== null) {
56
                $parameters[] = $tmp;
57
            }
58
        }
59
60
        return $parameters;
61
    }
62
63
    protected function stringToParam(string $input, string $class): ?AbstractParameter
64
    {
65
        $input = trim($input);
66
        $regex = '/^(.*) *(?:=|:) *(.+)/u';
67
68
        $matches = [];
69
        \preg_match($regex, $input, $matches);
70
        dump($matches);
71
        if (!empty($matches)) {
72
            [$raw, $name, $value] = $matches;
73
            $value = trim($value);
74
75
            //Dont allow empty names or values (these are a sign of an invalid extracted string)
76
            if (empty($name) || empty($value)) {
77
                return null;
78
            }
79
80
            /** @var AbstractParameter $parameter */
81
            $parameter = new $class();
82
            $parameter->setName(trim($name));
83
            $parameter->setValueText($value);
84
85
            return $parameter;
86
        }
87
88
        return null;
89
    }
90
91
    protected function splitString(string $input): array
92
    {
93
        //Allow comma as limiter (include space, to prevent splitting in german style numbers)
94
        $input = str_replace(static::ALLOWED_PARAM_SEPARATORS, ";", $input);
95
        return explode(";", $input);
96
    }
97
}