ImplementationProvider::getCallableCode()   B
last analyzed

Complexity

Conditions 9
Paths 64

Size

Total Lines 39
Code Lines 23

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 9
eloc 23
nc 64
nop 1
dl 0
loc 39
rs 8.0555
c 1
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Facile\OpenIDClient\ConformanceTest\Provider;
6
7
use function array_map;
8
use function array_pop;
9
use function array_push;
10
use function array_shift;
11
use function array_slice;
12
use function array_unshift;
13
use Closure;
14
use function file;
15
use function implode;
16
use function is_callable;
17
use function preg_match;
18
use function preg_replace;
19
use ReflectionFunction;
20
use function str_repeat;
21
use function strlen;
22
23
class ImplementationProvider
24
{
25
    /** @var int */
26
    private $indent;
27
28
    /**
29
     * ImplementationProvider constructor.
30
     * @param int $indent
31
     */
32
    public function __construct(int $indent = 4)
33
    {
34
        $this->indent = $indent;
35
    }
36
37
    public function getCallableCode(callable $closure)
38
    {
39
        if (is_callable($closure)) {
40
            $closure = Closure::fromCallable($closure);
41
        }
42
43
        $r = new ReflectionFunction($closure);
44
        $lines = file($r->getFileName());
45
        $lines = array_slice($lines, $r->getStartLine(), $r->getEndLine() - $r->getStartLine());
46
        if (preg_match('/^ *{ *$/', $lines[0] ?? '')) {
47
            unset($lines[0]);
48
        }
49
50
        $firstLine = array_shift($lines) ?: '';
51
52
        if (! preg_match('/^ *{ *$/', $firstLine)) {
53
            array_unshift($lines, $firstLine);
54
        }
55
56
        $lastLine = array_pop($lines) ?: '';
57
        if (! preg_match('/^ *} *$/', $lastLine)) {
58
            $lines[] = $lastLine;
59
        }
60
61
        // remove spaces based on first line
62
        if (preg_match('/^( +)/', $lines[0] ?? '', $matches)) {
63
            $toTrim = strlen($matches[1]);
64
            $lines = array_map(static function (string $line) use ($toTrim) {
65
                return preg_replace(sprintf('/^ {0,%d}/', $toTrim), '', $line);
66
            }, $lines);
67
        }
68
69
        if ($this->indent) {
70
            $lines = array_map(function (string $line) {
71
                return str_repeat(' ', $this->indent) . $line;
72
            }, $lines);
73
        }
74
75
        return implode('', $lines);
76
    }
77
}
78