Completed
Push — master ( 5c84c5...c7f8f4 )
by Marius
01:51
created

WorkspaceConfigurationHelper   A

Complexity

Total Complexity 15

Size/Duplication

Total Lines 182
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 2

Test Coverage

Coverage 99.13%

Importance

Changes 0
Metric Value
wmc 15
lcom 1
cbo 2
dl 0
loc 182
ccs 114
cts 115
cp 0.9913
rs 10
c 0
b 0
f 0

8 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 5 1
A setupServerMappings() 0 11 3
B addServer() 0 50 5
A configureComposer() 0 25 1
A configureFileTemplateScheme() 0 21 1
A setupPhpUnitRunConfiguration() 0 32 1
A generateId() 0 10 1
A ensureWorkspaceFileExists() 0 15 2
1
<?php
2
declare(strict_types=1);
3
4
namespace Paysera\PhpStormHelper\Service;
5
6
use RuntimeException;
7
use Symfony\Component\Filesystem\Filesystem;
8
9
class WorkspaceConfigurationHelper
10
{
11
    private $domHelper;
12
    private $filesystem;
13
14 23
    public function __construct(DomHelper $domHelper, Filesystem $filesystem)
15
    {
16 23
        $this->domHelper = $domHelper;
17 23
        $this->filesystem = $filesystem;
18 23
    }
19
20 16
    public function setupServerMappings(string $pathToWorkspaceXml, array $serverMappings)
21
    {
22 16
        foreach ($serverMappings as $serverMapping) {
23 11
            $parts = explode('@', $serverMapping);
24 11
            if (count($parts) !== 2) {
25
                throw new RuntimeException(sprintf('Invalid server mapping format: %s', $serverMapping));
26
            }
27
28 11
            $this->addServer($pathToWorkspaceXml, $parts[0], $parts[1]);
29
        }
30 16
    }
31
32 11
    private function addServer(string $pathToWorkspaceXml, string $hostWithPort, string $remoteRoot)
33
    {
34 11
        if (strpos($hostWithPort, ':') === false) {
35 8
            $host = $hostWithPort;
36 8
            $name = $host;
37 8
            $port = null;
38
        } else {
39 3
            $parts = explode(':', $hostWithPort, 2);
40 3
            $host = $parts[0];
41 3
            $port = $parts[1];
42 3
            $name = $port === '80' ? $host : $hostWithPort;
43
        }
44
45 11
        $this->ensureWorkspaceFileExists($pathToWorkspaceXml);
46 11
        $document = $this->domHelper->loadDocument($pathToWorkspaceXml);
47
48 11
        $projectElement = $this->domHelper->findNode($document, 'project');
49 11
        $serversComponent = $this->domHelper->findOrCreateChildNode(
50 11
            $projectElement,
51 11
            'component',
52 11
            ['name' => 'PhpServers']
53
        );
54
55 11
        $internalNode = $this->domHelper->findOrCreateChildNode($serversComponent, 'servers');
56
57 11
        $serverNode = $this->domHelper->findOptionalNode($internalNode, 'server', ['host' => $host, 'port' => $port]);
58 11
        if ($serverNode === null) {
59 8
            $serverNode = $document->createElement('server');
60 8
            $serverNode->setAttribute('id', $this->generateId($name));
61 8
            $internalNode->appendChild($serverNode);
62
        }
63
64 11
        $serverNode->setAttribute('host', $host);
65 11
        $serverNode->setAttribute('name', $name);
66 11
        if ($port === null) {
67 8
            $serverNode->removeAttribute('port');
68
        } else {
69 3
            $serverNode->setAttribute('port', $port);
70
        }
71 11
        $serverNode->setAttribute('use_path_mappings', 'true');
72
73 11
        $pathMappings = $this->domHelper->findOrCreateChildNode($serverNode, 'path_mappings');
74
75 11
        $this->domHelper->removeNodes($pathMappings, 'mapping');
76 11
        $mapping = $this->domHelper->findOrCreateChildNode($pathMappings, 'mapping');
77 11
        $mapping->setAttribute('local-root', '$PROJECT_DIR$');
78 11
        $mapping->setAttribute('remote-root', $remoteRoot);
79
80 11
        $this->domHelper->saveDocument($pathToWorkspaceXml, $document);
81 11
    }
82
83 8
    public function configureComposer(string $pathToWorkspaceXml, string $composerExecutable = 'composer')
84
    {
85 8
        $this->ensureWorkspaceFileExists($pathToWorkspaceXml);
86 8
        $document = $this->domHelper->loadDocument($pathToWorkspaceXml);
87
88 8
        $projectElement = $this->domHelper->findNode($document, 'project');
89
90 8
        $component = $this->domHelper->findOrCreateChildNode(
91 8
            $projectElement,
92 8
            'component',
93 8
            ['name' => 'ComposerSettings']
94
        );
95
96 8
        $component->setAttribute('doNotAsk', 'true');
97 8
        $component->setAttribute('synchronizationState', 'SYNCHRONIZE');
98 8
        $component->setAttribute('updatePackages', 'false');
99
100 8
        $pharConfigPath = $this->domHelper->findOrCreateChildNode($component, 'pharConfigPath');
101 8
        $pharConfigPath->nodeValue = '$PROJECT_DIR$/composer.json';
102
103 8
        $executablePath = $this->domHelper->findOrCreateChildNode($component, 'executablePath');
104 8
        $executablePath->nodeValue = $composerExecutable;
105
106 8
        $this->domHelper->saveDocument($pathToWorkspaceXml, $document);
107 8
    }
108
109 8
    public function configureFileTemplateScheme(string $pathToWorkspaceXml)
110
    {
111 8
        $this->ensureWorkspaceFileExists($pathToWorkspaceXml);
112 8
        $document = $this->domHelper->loadDocument($pathToWorkspaceXml);
113
114 8
        $projectElement = $this->domHelper->findNode($document, 'project');
115
116 8
        $component = $this->domHelper->findOrCreateChildNode(
117 8
            $projectElement,
118 8
            'component',
119 8
            ['name' => 'FileTemplateManagerImpl']
120
        );
121 8
        $option = $this->domHelper->findOrCreateChildNode(
122 8
            $component,
123 8
            'option',
124 8
            ['name' => 'SCHEME']
125
        );
126 8
        $option->setAttribute('value', 'Project');
127
128 8
        $this->domHelper->saveDocument($pathToWorkspaceXml, $document);
129 8
    }
130
131 6
    public function setupPhpUnitRunConfiguration(string $pathToWorkspaceXml)
132
    {
133 6
        $this->ensureWorkspaceFileExists($pathToWorkspaceXml);
134 6
        $document = $this->domHelper->loadDocument($pathToWorkspaceXml);
135
136 6
        $projectElement = $this->domHelper->findNode($document, 'project');
137
138 6
        $component = $this->domHelper->findOrCreateChildNode(
139 6
            $projectElement,
140 6
            'component',
141 6
            ['name' => 'RunManager']
142
        );
143 6
        $configuration = $this->domHelper->findOrCreateChildNode(
144 6
            $component,
145 6
            'configuration',
146 6
            ['name' => 'PHPUnit', 'type' => 'PHPUnitRunConfigurationType', 'factoryName' => 'PHPUnit']
147
        );
148
149 6
        $testRunnerNode = $this->domHelper->findOrCreateChildNode(
150 6
            $configuration,
151 6
            'TestRunner'
152
        );
153 6
        $testRunnerNode->setAttribute('scope', 'XML');
154
155 6
        $methodNode = $this->domHelper->findOrCreateChildNode(
156 6
            $configuration,
157 6
            'method'
158
        );
159 6
        $methodNode->setAttribute('v', '2');
160
161 6
        $this->domHelper->saveDocument($pathToWorkspaceXml, $document);
162 6
    }
163
164 8
    private function generateId(string $name)
165
    {
166 8
        $hash = sha1($name);
167 8
        return substr($hash, 0, 8) . '-'
168 8
            . substr($hash, 8, 4) . '-'
169 8
            . substr($hash, 12, 4) . '-'
170 8
            . substr($hash, 16, 4) . '-'
171 8
            . substr($hash, 20, 12)
172
        ;
173
    }
174
175 23
    private function ensureWorkspaceFileExists(string $pathToWorkspaceXml)
176
    {
177 23
        if (file_exists($pathToWorkspaceXml)) {
178 23
            return;
179
        }
180
181
        $emptyWorkspaceFile = <<<'FILE'
182 5
<?xml version="1.0" encoding="UTF-8"?>
183
<project version="4"/>
184
FILE;
185
186 5
        $directory = dirname($pathToWorkspaceXml);
187 5
        $this->filesystem->mkdir($directory);
188 5
        $this->filesystem->dumpFile($pathToWorkspaceXml, $emptyWorkspaceFile);
189 5
    }
190
}
191