Test Setup Failed
Push — master ( c6f3fc...610181 )
by Marcel
02:38
created

SaasClientService   A

Complexity

Total Complexity 18

Size/Duplication

Total Lines 128
Duplicated Lines 0 %

Importance

Changes 6
Bugs 2 Features 1
Metric Value
eloc 52
c 6
b 2
f 1
dl 0
loc 128
rs 10
wmc 18

8 Methods

Rating   Name   Duplication   Size   Complexity  
A createClient() 0 14 2
B tryGetCurrentClient() 0 36 8
A getCurrentClient() 0 4 1
A saveSaasClientSession() 0 3 1
A getCurrentHttpHost() 0 9 2
A __construct() 0 6 1
A discoverClient() 0 12 2
A resetSaasClientSession() 0 3 1
1
<?php
2
3
/*
4
 * This file is part of the SaasProviderBundle package.
5
 * (c) Fluxter <http://fluxter.net/>
6
 * For the full copyright and license information, please view the LICENSE
7
 * file that was distributed with this source code.
8
 */
9
10
namespace Fluxter\SaasProviderBundle\Service;
11
12
use Doctrine\ORM\EntityManagerInterface;
13
use Exception;
14
use Fluxter\SaasProviderBundle\Model\Exception\ClientCouldNotBeDiscoveredException;
15
use Fluxter\SaasProviderBundle\Model\SaasClientInterface;
16
use Fluxter\SaasProviderBundle\Model\SaasParameterInterface;
17
use Symfony\Component\DependencyInjection\ContainerInterface;
18
use Symfony\Component\HttpFoundation\RequestStack;
19
use Symfony\Component\HttpFoundation\Session\SessionInterface;
20
21
class SaasClientService
22
{
23
    private const SaasClientSessionIndex = 'SAASCLIENT';
24
25
    /** @var EntityManagerInterface */
26
    private $em;
27
28
    /** @var SessionInterface */
29
    private $session;
30
31
    /** @var string */
32
    private $saasClientEntity;
33
34
    /** @var RequestStack */
35
    private $requestStack;
36
37
    public function __construct(ContainerInterface $container, EntityManagerInterface $em, SessionInterface $session, RequestStack $requestStack)
38
    {
39
        $this->em = $em;
40
        $this->session = $session;
41
        $this->saasClientEntity = $container->getParameter('saas_provider.client_entity');
42
        $this->requestStack = $requestStack;
43
    }
44
45
    public function createClient(array $parameters)
46
    {
47
        /** @var SaasClientInterface $client */
48
        $client = new $this->saasClientEntity();
49
50
        /** @var SaasParameterInterface $parameter */
51
        foreach ($parameters as $parameter) {
52
            $client->addParameter($parameter);
53
        }
54
55
        $this->em->persist($client);
56
        $this->em->flush($client);
0 ignored issues
show
Unused Code introduced by
The call to Doctrine\Persistence\ObjectManager::flush() has too many arguments starting with $client. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

56
        $this->em->/** @scrutinizer ignore-call */ 
57
                   flush($client);

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
57
58
        return $client;
59
    }
60
61
    public function tryGetCurrentClient(bool $autodiscover = true): ?SaasClientInterface
62
    {
63
        try {
64
            if (!$this->session->has(self::SaasClientSessionIndex) || null == $this->session->get(self::SaasClientSessionIndex)) {
65
                if ($autodiscover) {
66
                    $this->discoverClient();
67
                    return $this->tryGetCurrentClient(false);
68
                }
69
70
                return null;
71
            }
72
73
            $repo = $this->em->getRepository($this->saasClientEntity);
74
            /** @var SaasClientInterface $client */
75
            $client = $repo->findOneById($this->session->get(self::SaasClientSessionIndex));
0 ignored issues
show
Bug introduced by
The method findOneById() does not exist on Doctrine\Persistence\ObjectRepository. Did you maybe mean findOneBy()? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

75
            /** @scrutinizer ignore-call */ 
76
            $client = $repo->findOneById($this->session->get(self::SaasClientSessionIndex));

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
76
            if (null == $client) {
77
                throw new ClientCouldNotBeDiscoveredException();
78
            }
79
80
            // Validate
81
            $url = $this->getCurrentHttpHost();
82
            if (strtolower($client->getUrl()) != strtolower($url)) {
83
                $this->resetSaasClientSession();
84
                $this->discoverClient();
85
86
                return $this->tryGetCurrentClient(false);
87
            }
88
89
            if (null == $client) {
90
                throw new ClientCouldNotBeDiscoveredException();
91
            }
92
93
            return $client;
94
        }
95
        catch(Exception $ex) {
96
            return null;
97
        }
98
    }
99
100
    /**
101
     * Returns the current client, recognized by the url and the client entity.
102
     *
103
     * @return SaasClientInterface|null
104
     */
105
    public function getCurrentClient(bool $autodiscover = true): SaasClientInterface
106
    {
107
        $client = $this->tryGetCurrentClient($autodiscover);
108
        return $client;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $client could return the type null which is incompatible with the type-hinted return Fluxter\SaasProviderBund...del\SaasClientInterface. Consider adding an additional type-check to rule them out.
Loading history...
109
    }
110
111
    /**
112
     * Returns the current http host in lower case.
113
     * For example: "http://localhost:8000" returns "localhost"
114
     * https://test.test.de would return "test.test.de".
115
     */
116
    private function getCurrentHttpHost(): string
117
    {
118
        $url = $this->requestStack->getCurrentRequest()->getHttpHost();
119
        $url = strtolower($url);
120
        if (false !== strpos($url, ':')) {
121
            $url = preg_replace('/:(.*)/', '', $url);
122
        }
123
124
        return strtolower($url);
125
    }
126
127
    private function discoverClient(): ?SaasClientInterface
128
    {
129
        $url = $this->getCurrentHttpHost();
130
        $repo = $this->em->getRepository($this->saasClientEntity);
131
        $client = $repo->findOneBy(['url' => $url]);
132
        if (null == $client) {
133
            return null;
134
        }
135
136
        $this->saveSaasClientSession($client);
137
138
        return $client;
139
    }
140
141
    private function resetSaasClientSession()
142
    {
143
        $this->session->set(self::SaasClientSessionIndex, null);
144
    }
145
146
    private function saveSaasClientSession(SaasClientInterface $client)
147
    {
148
        $this->session->set(self::SaasClientSessionIndex, $client->getId());
149
    }
150
}
151