Passed
Push — master ( cef8d3...1f0b7e )
by Allan
02:45
created

BasePathComponent::expandPathVariables()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 28
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 16
nc 3
nop 2
dl 0
loc 28
rs 9.7333
c 0
b 0
f 0
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
        $mutationRules = $this->templateUtils->collectValueMutationRules($template, array($variablePattern));
89
90
        $templateVariables = array_replace(
91
            $this->templateUtils->applyMutations(
92
                array_replace($pathVariables, $extraVariables),
93
                $mutationRules,
94
                ' :-_.'
95
            ),
96
            $pathVariables,
97
            $extraVariables
98
        );
99
100
        $source = $this->templateUtils->compose(
101
            $template . ($sourceTags ? ('#' . $sourceTags) : ''),
102
            $templateVariables,
103
            array_fill_keys(array($variablePattern), false)
104
        );
105
106
        $filename = basename($source);
107
108
        if (substr($label, -strlen($filename)) == $filename) {
109
            $label = str_replace(
110
                $filename,
111
                preg_replace('/\s{2,}/', ' ', preg_replace('/[^A-Za-z0-9]/', ' ', strtok($filename, '.'))),
112
                $label
113
            );
114
        }
115
116
        return array(
117
            PatchDefinition::LABEL => $label,
118
            PatchDefinition::SOURCE => $source
119
        );
120
    }
121
    
122
    private function expandPathVariables(array $pathVariables, array $mutationNamesMap)
123
    {
124
        $nameParts = array_map(function ($part) {
125
            $part = strtolower(
126
                preg_replace(
127
                    array('/([A-Z]+)([A-Z][a-z])/', '/([a-z\d])([A-Z])/'),
128
                    array('\\1_\\2', '\\1_\\2'),
129
                    str_replace('_', '.', $part)
130
                )
131
            );
132
133
            return preg_replace('/\s{2,}/', ' ', str_replace(array(' ', '_', '-', '.', '/', ':'), ' ', $part));
134
        }, $pathVariables);
135
136
        $mutationAppliers = $this->createMutationAppliers();
137
138
        $pathVariables = array();
139
140
        foreach ($nameParts as $name => $value) {
141
            $variableName = $mutationNamesMap[$name];
142
143
            foreach ($mutationAppliers as $mutationApplier) {
144
                $mutationName = $mutationApplier($variableName);
145
                $pathVariables[$mutationName] = $mutationApplier($value);
146
            }
147
        }
148
        
149
        return $pathVariables;
150
    }
151
152
    private function resolveTemplate($ownerConfig, $packageName)
153
    {
154
        $templates = $ownerConfig[PluginConfig::PATCHES_BASE];
155
156
        $vendorName = strtok($packageName, '/');
157
158
        if (is_array($templates)) {
159
            if (isset($templates[$packageName])) {
160
                return $templates[$packageName];
161
            } elseif (isset($templates[$vendorName])) {
162
                return $templates[$vendorName];
163
            } elseif ($templates[PluginConfig::PATCHES_BASE_DEFAULT]) {
164
                return $templates[PluginConfig::PATCHES_BASE_DEFAULT];
165
            } else {
166
                return reset($templates);
167
            }
168
        }
169
170
        return $templates;
171
    }
172
173
    private function createMutationAppliers()
174
    {
175
        return array(
176
            function ($value) {
177
                return str_replace(' ', '', $value);
178
            },
179
            function ($value) {
180
                return str_replace(' ', '', ucwords($value));
181
            },
182
            function ($value) {
183
                return str_replace(' ', '', ucfirst($value));
184
            },
185
            function ($value) {
186
                return str_replace(' ', '-', $value);
187
            },
188
            function ($value) {
189
                return str_replace(' ', '_', $value);
190
            },
191
        );
192
    }
193
}
194