ProfilerFactory::create()   B
last analyzed

Complexity

Conditions 5
Paths 7

Size

Total Lines 36
Code Lines 23

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 25
CRAP Score 5

Importance

Changes 2
Bugs 0 Features 1
Metric Value
c 2
b 0
f 1
dl 0
loc 36
ccs 25
cts 25
cp 1
rs 8.439
cc 5
eloc 23
nc 7
nop 1
crap 5
1
<?php
2
3
namespace Ndrx\Profiler;
4
5
use Ndrx\Profiler\Collectors\Data\CpuUsage;
6
use Ndrx\Profiler\Collectors\Data\Log;
7
use Ndrx\Profiler\Collectors\Data\PhpVersion;
8
use Ndrx\Profiler\Collectors\Data\Request;
9
use Ndrx\Profiler\Collectors\Data\Timeline;
10
use Ndrx\Profiler\Components\Logs\Monolog;
11
use Ndrx\Profiler\Components\Logs\Simple;
12
use Ndrx\Profiler\Components\Timeline as TimelineComponent;
13
use Ndrx\Profiler\DataSources\File;
14
use Ndrx\Profiler\DataSources\Memory;
15
use Symfony\Component\OptionsResolver\Exception\AccessException;
16
use Symfony\Component\OptionsResolver\Exception\InvalidOptionsException;
17
use Symfony\Component\OptionsResolver\Exception\MissingOptionsException;
18
use Symfony\Component\OptionsResolver\Exception\NoSuchOptionException;
19
use Symfony\Component\OptionsResolver\Exception\OptionDefinitionException;
20
use Symfony\Component\OptionsResolver\Exception\UndefinedOptionsException;
21
use Symfony\Component\OptionsResolver\OptionsResolver;
22
23
/**
24
 * Class ProfilerFactory
25
 * @package Ndrx\Profiler
26
 */
27
class ProfilerFactory
28
{
29
    const OPTION_ENABLE = 'enable';
30
    const OPTION_ENVIRONMENT = 'environment';
31
    const OPTION_DATASOURCE_PROFILES_FOLDER = 'dataSourceProfilesFolders';
32
    const OPTION_DATASOURCE_CLASS = 'dataSourceClass';
33
    const OPTION_LOGGER = 'logger';
34
    const OPTION_COLLECTORS = 'collectors';
35
36
    /**
37
     * @var ProfilerInterface
38
     */
39
    protected static $profiler;
40
41
    /**
42
     * @return ProfilerInterface
43
     * @throws \RuntimeException
44
     */
45
    public static function getProfiler()
46
    {
47
        if (self::$profiler === null) {
48
            throw new \RuntimeException('Before getting profiler you need to create one');
49
        }
50
51
        return self::$profiler;
52
    }
53
54
    /**
55
     * @param array $options
56
     * @return Profiler|ProfilerInterface
57
     * @throws \RuntimeException
58
     * @throws AccessException
59
     * @throws UndefinedOptionsException
60
     * @throws MissingOptionsException
61
     * @throws InvalidOptionsException
62
     * @throws NoSuchOptionException
63
     * @throws OptionDefinitionException
64
     */
65 100
    public static function build(array $options = [])
66
    {
67 100
        self::$profiler = (new self())->create($options);
68
69 100
        return self::$profiler;
70
    }
71
72
    /**
73
     * @param array $options
74
     * @return Profiler
75
     *
76
     * @throws \RuntimeException
77
     * @throws AccessException
78
     * @throws UndefinedOptionsException
79
     * @throws MissingOptionsException
80
     * @throws InvalidOptionsException
81
     * @throws NoSuchOptionException
82
     * @throws OptionDefinitionException
83
     */
84 100
    public function create(array $options = [])
85
    {
86 100
        $options = $this->resolveOptions($options);
87
88 100
        if (!$options[self::OPTION_ENABLE]) {
89 2
            return new NullProfiler();
90
        }
91
92 98
        if ($options[self::OPTION_ENVIRONMENT] !== null) {
93 2
            Profiler::$environment = $options[self::OPTION_ENVIRONMENT];
94 2
        }
95
96 98
        $profiler = new Profiler();
97
98 98
        switch ($options[self::OPTION_DATASOURCE_CLASS]) {
99 98
            default:
100 98
            case File::class:
101 96
                $datasource = new File($options[self::OPTION_DATASOURCE_PROFILES_FOLDER]);
102 96
                break;
103 2
            case Memory::class:
104 2
                $datasource = new Memory();
105 98
        }
106
107 98
        $profiler->setDataSource($datasource);
108 98
        $profiler->registerCollectorClasses($options[self::OPTION_COLLECTORS]);
109
110 98
        $dispatcher = $profiler->getContext()->getProcess()->getDispatcher();
111 98
        $className = $options['logger'];
112 98
        $logger = new $className();
113 98
        $logger->setDispatcher($dispatcher);
114 98
        $profiler->setLogger($logger);
115
116 98
        $profiler->setTimeline(new TimelineComponent($dispatcher));
117
118 98
        return $profiler;
119
    }
120
121
122
    /**
123
     * @param array $options
124
     * @return array
125
     * @throws AccessException
126
     * @throws UndefinedOptionsException
127
     * @throws MissingOptionsException
128
     * @throws InvalidOptionsException
129
     * @throws NoSuchOptionException
130
     * @throws OptionDefinitionException
131
     */
132 100
    protected function resolveOptions(array $options = [])
133
    {
134 100
        $resolver = new OptionsResolver();
135 100
        $this->configureOptions($resolver);
136
137 100
        return $resolver->resolve($options);
138
    }
139
140
    /**
141
     * @param OptionsResolver $resolver
142
     * @throws AccessException
143
     * @throws UndefinedOptionsException
144
     */
145 100
    public function configureOptions(OptionsResolver $resolver)
146
    {
147 100
        $resolver->setDefaults([
148 100
            self::OPTION_ENABLE => true,
149 100
            self::OPTION_ENVIRONMENT => null,
150 100
            self::OPTION_DATASOURCE_PROFILES_FOLDER => '/tmp/profiler/',
151 100
            self::OPTION_DATASOURCE_CLASS => File::class,
152 100
            self::OPTION_LOGGER => Simple::class,
153 100
            self::OPTION_COLLECTORS => [
154 100
                CpuUsage::class,
155 100
                Log::class,
156 100
                PhpVersion::class,
157 100
                Timeline::class,
158
                Request::class
159 100
            ],
160 100
        ]);
161
162 100
        $resolver->setAllowedTypes(self::OPTION_DATASOURCE_PROFILES_FOLDER, 'string');
163 100
        $resolver->setAllowedValues(self::OPTION_LOGGER, [Monolog::class, Simple::class]);
164 100
        $resolver->setAllowedTypes(self::OPTION_COLLECTORS, 'array');
165 100
        $resolver->setAllowedTypes(self::OPTION_ENABLE, 'boolean');
166 100
        $resolver->setAllowedValues(self::OPTION_DATASOURCE_CLASS, [File::class, Memory::class]);
167 100
    }
168
}
169