Completed
Push — master ( 664783...554f9d )
by
unknown
15:59
created

ServiceManager::init()   B

Complexity

Conditions 6
Paths 9

Size

Total Lines 38
Code Lines 25

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 42

Importance

Changes 1
Bugs 0 Features 0
Metric Value
dl 0
loc 38
ccs 0
cts 33
cp 0
rs 8.439
c 1
b 0
f 0
cc 6
eloc 25
nc 9
nop 0
crap 42
1
<?php
2
/**
3
 * ParamConverter class for entry point to Analytics Bundle
4
 */
5
6
namespace Graviton\AnalyticsBundle\Manager;
7
8
use Graviton\AnalyticsBundle\Helper\JsonMapper;
9
use Graviton\AnalyticsBundle\Model\AnalyticModel;
10
use Symfony\Component\HttpFoundation\Request;
11
use Symfony\Component\Finder\Finder;
12
use Doctrine\Common\Cache\CacheProvider;
13
use Symfony\Component\HttpFoundation\RequestStack;
14
use Symfony\Component\Routing\Router;
15
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
16
use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException;
17
18
/**
19
 * Service Request Converter and startup for Analytics
20
 *
21
 * @author   List of contributors <https://github.com/libgraviton/graviton/graphs/contributors>
22
 * @license  http://opensource.org/licenses/gpl-license.php GNU Public License
23
 * @link     http://swisscom.ch
24
 */
25
class ServiceManager
26
{
27
    /** Cache name for services */
28
    const CACHE_KEY_SERVICES = 'analytics_services';
29
    const CACHE_KEY_SERVICES_TIME = 10;
30
    const CACHE_KEY_SERVICES_URLS = 'analytics_services_urls';
31
    const CACHE_KEY_SERVICES_URLS_TIME = 10;
32
    const CACHE_KEY_SERVICES_PREFIX = 'analytics_';
33
34
    /** @var Request */
35
    protected $request;
36
37
    /** @var AnalyticsManager */
38
    protected $analyticsManager;
39
40
    /** @var CacheProvider */
41
    protected $cacheProvider;
42
43
    /** @var Router */
44
    protected $router;
45
46
    /** @var string */
47
    protected $directory;
48
49
    /** @var array  */
50
    private $services = [];
51
52
    /**
53
     * ServiceConverter constructor.
54
     * @param RequestStack     $requestStack        Sf Request information service
55
     * @param AnalyticsManager $analyticsManager    Db Manager and query control
56
     * @param CacheProvider    $cacheProvider       Cache service
57
     * @param Router           $router              To manage routing generation
58
     * @param string           $definitionDirectory Where definitions are stored
59
     */
60
    public function __construct(
61
        RequestStack $requestStack,
62
        AnalyticsManager $analyticsManager,
63
        CacheProvider $cacheProvider,
64
        Router $router,
65
        $definitionDirectory
66
    ) {
67
        $this->request = $requestStack->getCurrentRequest();
68
        $this->analyticsManager = $analyticsManager;
69
        $this->cacheProvider = $cacheProvider;
70
        $this->router = $router;
71
        $this->directory = $definitionDirectory;
72
        $this->init();
73
    }
74
75
    /**
76
     * Scan base root directory for analytic definitions
77
     * @return void
78
     */
79
    private function init()
80
    {
81
        $this->services = $this->cacheProvider->fetch(self::CACHE_KEY_SERVICES);
82
83
        if (is_array($this->services)) {
84
            return;
85
        }
86
87
        $this->services = [];
88
        if (strpos($this->directory, 'vendor/graviton/graviton')) {
89
            $this->directory = str_replace('vendor/graviton/graviton/', '', $this->directory);
90
        }
91
        if (!is_dir($this->directory)) {
92
            return;
93
        }
94
95
        $finder = new Finder();
96
        $finder
97
            ->files()
98
            ->in($this->directory)
99
            ->path('/\/analytics\//i')
100
            ->name('*.json')
101
            ->notName('_*')
102
            ->sortByName();
103
104
        foreach ($finder as $file) {
105
            $key = $file->getFilename();
106
            $data = json_decode($file->getContents());
107
            if (json_last_error()) {
108
                throw new InvalidConfigurationException(
109
                    sprintf('Analytics file: %s could not be loaded due to error: ', $key, json_last_error_msg())
110
                );
111
            }
112
            $this->services[$data->route] = $data;
113
        }
114
115
        $this->cacheProvider->save(self::CACHE_KEY_SERVICES, $this->services, self::CACHE_KEY_SERVICES_TIME);
116
    }
117
118
    /**
119
     * Return array of available services
120
     *
121
     * @return array
122
     */
123
    public function getServices()
124
    {
125
        $services = $this->cacheProvider->fetch(self::CACHE_KEY_SERVICES_URLS);
126
        if (is_array($services)) {
127
            return $services;
128
        }
129
        $services = [];
130
        $r = $this->router;
131
        foreach ($this->services as $name => $service) {
132
            $services[] = [
133
                '$ref' => $r->generate('graviton_analytics_service', ['service' => $service->route], false),
134
                'profile' => $r->generate('graviton_analytics_service_schema', ['service' => $service->route], true)
135
            ];
136
        }
137
        $this->cacheProvider->save(self::CACHE_KEY_SERVICES_URLS, $services, self::CACHE_KEY_SERVICES_URLS_TIME);
138
        return $services;
139
    }
140
141
    /**
142
     * Get service definition
143
     *
144
     * @param string $name Route name for service
145
     * @throws NotFoundHttpException
146
     * @return AnalyticModel
147
     */
148
    private function getServiceSchemaByRoute($name)
149
    {
150
        // Locate the schema definition
151
        if (!array_key_exists($name, $this->services)) {
152
            throw new NotFoundHttpException(
153
                sprintf('Service Analytics for %s was not found', $name)
154
            );
155
        }
156
        $mapper = new JsonMapper();
157
        /** @var AnalyticModel $schema */
158
        $schema = $mapper->map($this->services[$name], new AnalyticModel());
159
        return $schema;
160
    }
161
162
    /**
163
     * Will map and find data for defined route
164
     *
165
     * @return array
166
     */
167
    public function getData()
168
    {
169
        $serviceRoute = $this->request->get('service');
170
        // Locate the schema definition
171
        $schema = $this->getServiceSchemaByRoute($serviceRoute);
172
        $cacheTime = $schema->getCacheTime();
173
174
        //Cached data if configured
175
        if ($cacheTime &&
176
            $cache = $this->cacheProvider->fetch(self::CACHE_KEY_SERVICES_PREFIX.$schema->getRoute())
177
        ) {
178
            return $cache;
179
        }
180
181
        $data = $this->analyticsManager->getData($schema);
0 ignored issues
show
Bug Compatibility introduced by
The expression $this->analyticsManager->getData($schema); of type array|object adds the type object to the return on line 187 which is incompatible with the return type documented by Graviton\AnalyticsBundle...ServiceManager::getData of type array.
Loading history...
182
183
        if ($cacheTime) {
184
            $this->cacheProvider->save(self::CACHE_KEY_SERVICES_PREFIX.$schema->getRoute(), $data, $cacheTime);
185
        }
186
187
        return $data;
188
    }
189
190
    /**
191
     * Locate and display service definition schema
192
     *
193
     * @return mixed
194
     */
195
    public function getSchema()
196
    {
197
        $serviceRoute = $this->request->get('service');
198
199
        // Locate the schema definition
200
        $schema =  $this->getServiceSchemaByRoute($serviceRoute);
201
202
        return $schema->getSchema();
203
    }
204
}
205