Passed
Push — master ( 5bb3b6...f2e35b )
by Allan
02:20
created

BasePathComponent   A

Complexity

Total Complexity 22

Size/Duplication

Total Lines 190
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 105
dl 0
loc 190
rs 10
c 0
b 0
f 0
wmc 22

6 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 3 1
A resolveTemplate() 0 19 5
C normalize() 0 90 11
A expandPathVariables() 0 28 3
A prepareTemplateValues() 0 14 1
A createMutationAppliers() 0 17 1
1
<?php
2
/**
3
 * Copyright © Vaimo Group. All rights reserved.
4
 * See LICENSE_VAIMO.txt for license details.
5
 */
6
namespace Vaimo\ComposerPatches\Patch\Definition\NormalizerComponents;
7
8
use Vaimo\ComposerPatches\Patch\Definition as PatchDefinition;
9
use Vaimo\ComposerPatches\Config as PluginConfig;
10
11
class BasePathComponent implements \Vaimo\ComposerPatches\Interfaces\DefinitionNormalizerComponentInterface
12
{
13
    /**
14
     * @var \Vaimo\ComposerPatches\Utils\TemplateUtils
15
     */
16
    private $templateUtils;
17
18
    public function __construct()
19
    {
20
        $this->templateUtils = new \Vaimo\ComposerPatches\Utils\TemplateUtils();
21
    }
22
23
    public function normalize($target, $label, array $data, array $ownerConfig)
24
    {
25
        if (!isset($ownerConfig[PluginConfig::PATCHES_BASE])) {
26
            return array();
27
        }
28
29
        $source = $data[PatchDefinition::SOURCE];
30
31
        if (parse_url($source, PHP_URL_SCHEME)) {
32
            return array();
33
        }
34
35
        if (isset($data[PatchDefinition::LABEL]) && is_numeric($label)) {
36
            $label = $data[PatchDefinition::LABEL];
37
        }
38
39
        if (strpos($data[PatchDefinition::PATH], DIRECTORY_SEPARATOR) === 0
40
            && file_exists($data[PatchDefinition::PATH])
41
        ) {
42
            return array(
43
                PatchDefinition::LABEL => $label,
44
                PatchDefinition::SOURCE => $source
45
            );
46
        }
47
48
        $template = $this->resolveTemplate($ownerConfig, $target);
49
50
        $nameParts = explode('/', $target);
51
52
        $sourceTags = '';
53
54
        if (strpos($source, '#') !== false) {
55
            $sourceSegments = explode('#', $source);
56
            $sourceTags = array_pop($sourceSegments);
57
            $source = implode('#', $sourceSegments);
58
        }
59
60
        $pathVariables = array(
61
            'file' => $source,
62
            'vendor' => array_shift($nameParts),
63
            'package' => implode('/', $nameParts),
64
            'label' => $label
65
        );
66
67
        $mutationNamesMap = array(
68
            'file' => 'file name',
69
            'vendor' => 'vendor name',
70
            'package' => 'module name',
71
            'label' => 'label value'
72
        );
73
        
74
        $pathVariables = $this->expandPathVariables($pathVariables, $mutationNamesMap);
75
        
76
        $extraVariables = array(
77
            'version' => preg_replace(
78
                '/[^A-Za-z0-9.-]/',
79
                '',
80
                strtok(reset($data[PatchDefinition::DEPENDS]) ?: '0.0.0', ' ')
81
            ),
82
            'file' => $source,
83
            'label' => $label
84
        );
85
86
        $variablePattern = '{{%s}}';
87
        
88
        $templateVariables = $this->prepareTemplateValues(
89
            $template,
90
            $variablePattern,
91
            array_replace($pathVariables, $extraVariables)
92
        );
93
        
94
        $source = $this->templateUtils->compose(
95
            $template . ($sourceTags ? ('#' . $sourceTags) : ''),
96
            $templateVariables,
97
            array_fill_keys(array($variablePattern), false)
98
        );
99
100
        $filename = basename($source);
101
102
        if (substr($label, -strlen($filename)) === $filename) {
103
            $label = str_replace(
104
                $filename,
105
                preg_replace('/\s{2,}/', ' ', preg_replace('/[^A-Za-z0-9]/', ' ', strtok($filename, '.'))),
106
                $label
107
            );
108
        }
109
110
        return array(
111
            PatchDefinition::LABEL => $label,
112
            PatchDefinition::SOURCE => $source
113
        );
114
    }
115
    
116
    private function prepareTemplateValues($template, $variablePattern, $variableValues)
117
    {
118
        $mutationRules = $this->templateUtils->collectValueMutationRules(
119
            $template,
120
            array($variablePattern)
121
        );
122
123
        return array_replace(
124
            $this->templateUtils->applyMutations(
125
                $variableValues,
126
                $mutationRules,
127
                ' :-_.'
128
            ),
129
            $variableValues
130
        );
131
    }
132
    
133
    private function expandPathVariables(array $pathVariables, array $mutationNamesMap)
134
    {
135
        $normalizedVariables = array_map(function ($part) {
136
            $part = strtolower(
137
                preg_replace(
138
                    array('/([A-Z]+)([A-Z][a-z])/', '/([a-z\d])([A-Z])/'),
139
                    array('\\1_\\2', '\\1_\\2'),
140
                    str_replace('_', '.', $part)
141
                )
142
            );
143
144
            return preg_replace('/\s{2,}/', ' ', str_replace(array(' ', '_', '-', '.', '/', ':'), ' ', $part));
145
        }, $pathVariables);
146
147
        $mutationAppliers = $this->createMutationAppliers();
148
149
        $pathVariables = array();
150
151
        foreach ($normalizedVariables as $name => $value) {
152
            $variableName = $mutationNamesMap[$name];
153
154
            foreach ($mutationAppliers as $mutationApplier) {
155
                $mutationName = $mutationApplier($variableName);
156
                $pathVariables[$mutationName] = $mutationApplier($value);
157
            }
158
        }
159
        
160
        return $pathVariables;
161
    }
162
163
    private function resolveTemplate($ownerConfig, $packageName)
164
    {
165
        $templates = $ownerConfig[PluginConfig::PATCHES_BASE];
166
167
        $vendorName = strtok($packageName, '/');
168
169
        if (is_array($templates)) {
170
            if (isset($templates[$packageName])) {
171
                return $templates[$packageName];
172
            } elseif (isset($templates[$vendorName])) {
173
                return $templates[$vendorName];
174
            } elseif ($templates[PluginConfig::PATCHES_BASE_DEFAULT]) {
175
                return $templates[PluginConfig::PATCHES_BASE_DEFAULT];
176
            }
177
178
            return reset($templates);
179
        }
180
181
        return $templates;
182
    }
183
184
    private function createMutationAppliers()
185
    {
186
        return array(
187
            function ($value) {
188
                return str_replace(' ', '', $value);
189
            },
190
            function ($value) {
191
                return str_replace(' ', '', ucwords($value));
192
            },
193
            function ($value) {
194
                return str_replace(' ', '', ucfirst($value));
195
            },
196
            function ($value) {
197
                return str_replace(' ', '-', $value);
198
            },
199
            function ($value) {
200
                return str_replace(' ', '_', $value);
201
            },
202
        );
203
    }
204
}
205