Completed
Push — master ( 44461e...067e0f )
by Nikola
04:28
created

UnderscoredClassNamespacePrefix::underscore()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 10
Code Lines 5

Duplication

Lines 10
Ratio 100 %

Code Coverage

Tests 5
CRAP Score 2

Importance

Changes 0
Metric Value
dl 10
loc 10
ccs 5
cts 5
cp 1
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 5
nc 2
nop 1
crap 2
1
<?php
2
/*
3
 * This file is part of the Doctrine Naming Strategy Bundle, an RunOpenCode project.
4
 *
5
 * (c) 2017 RunOpenCode
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 */
10
namespace RunOpenCode\Bundle\DoctrineNamingStrategy\NamingStrategy;
11
12
use Doctrine\ORM\Mapping\NamingStrategy;
13
use RunOpenCode\Bundle\DoctrineNamingStrategy\Exception\RuntimeException;
14
15
/**
16
 * Class UnderscoredClassNamespacePrefix
17
 *
18
 * @package RunOpenCode\Bundle\DoctrineNamingStrategy\NamingStrategy
19
 */
20
class UnderscoredClassNamespacePrefix implements NamingStrategy
21
{
22
    /**
23
     * @var int
24
     */
25
    protected $case = CASE_LOWER;
26
27
    /**
28
     * @var bool
29
     */
30
    protected $joinTableFieldSuffix;
31
32
    /**
33
     * @var array
34
     */
35
    protected $whitelist;
36
37
    /**
38
     * @var array
39
     */
40
    protected $blacklist;
41
42
    /**
43
     * @var array
44
     */
45
    protected $map;
46
47 20
    public function __construct(array $configuration = array())
48
    {
49 20
        $configuration = array_merge([
50 20
            'case' => CASE_LOWER,
51
            'map' => [],
52
            'whitelist' => [],
53
            'blacklist' => [],
54
            'joinTableFieldSuffix' => true
55
        ], $configuration);
56
57 20
        if (count($configuration['whitelist']) > 0 && count($configuration['blacklist']) > 0) {
58 1
            throw new RuntimeException('You can use whitelist or blacklist or none of mentioned lists, but not booth.');
59
        }
60
61 19
        $this->case = $configuration['case'];
62
        $this->map = array_map(\Closure::bind(function ($prefix) {
63 12
            return $this->underscore($prefix);
64 19
        }, $this), $configuration['map']);
65
        $this->blacklist = array_map(function($fqcn) {
66 1
            return ltrim($fqcn, '\\');
67 19
        }, $configuration['blacklist']);
68 19
        $this->whitelist = array_map(function($fqcn) {
69 1
            return ltrim($fqcn, '\\');
70 19
        }, $configuration['whitelist']);
71 19
        $this->joinTableFieldSuffix = $configuration['joinTableFieldSuffix'];
72 19
    }
73
74
    /**
75
     * {@inheritdoc}
76
     */
77 12 View Code Duplication
    public function classToTableName($className)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
78
    {
79 12
        $prefix = $this->getTableNamePrefix($className);
80
81 12
        if (strpos($className, '\\') !== false) {
82 12
            $className = substr($className, strrpos($className, '\\') + 1);
83
        }
84
85 12
        return $prefix.$this->underscore($className);
86
    }
87
88
    /**
89
     * {@inheritdoc}
90
     */
91 4
    public function propertyToColumnName($propertyName, $className = null)
92
    {
93 4
        return $this->underscore($propertyName);
94
    }
95
96
    /**
97
     * {@inheritdoc}
98
     */
99 2
    public function embeddedFieldToColumnName($propertyName, $embeddedColumnName, $className = null, $embeddedClassName = null)
100
    {
101 2
        return $this->underscore($propertyName).'_'.$this->underscore($embeddedColumnName);
102
    }
103
104
    /**
105
     * {@inheritdoc}
106
     */
107 5
    public function referenceColumnName()
108
    {
109 5
        return $this->case === CASE_UPPER ?  'ID' : 'id';
110
    }
111
112
    /**
113
     * {@inheritdoc}
114
     */
115 2
    public function joinColumnName($propertyName, $className = null)
116
    {
117 2
        return $this->underscore($propertyName) . '_' . $this->referenceColumnName();
118
    }
119
120
    /**
121
     * {@inheritdoc}
122
     */
123 3 View Code Duplication
    public function joinTableName($sourceEntity, $targetEntity, $propertyName = null)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
124
    {
125 3
        $tableName = $this->classToTableName($sourceEntity).'_'.$this->classToTableName($targetEntity);
126
127
        return
128
            $tableName
129
            .
130 3
            (($this->joinTableFieldSuffix && null !== $propertyName) ? '_'.$this->propertyToColumnName($propertyName, $sourceEntity) : '');
131
    }
132
133
    /**
134
     * {@inheritdoc}
135
     */
136 2
    public function joinKeyColumnName($entityName, $referencedColumnName = null)
137
    {
138 2
        return $this->classToTableName($entityName).'_'.
139 2
            ($referencedColumnName ? $this->underscore($referencedColumnName) : $this->referenceColumnName());
140
    }
141
142
    /**
143
     * Get prefix for table from map.
144
     *
145
     * @param string $className
146
     * @return string
147
     */
148 12
    protected function getTableNamePrefix($className)
149
    {
150 12
        $className = ltrim($className, '\\');
151
152 12
        foreach ($this->blacklist as $blacklist) {
153
154 1
            if (strpos($className, $blacklist) === 0) {
155 1
                return '';
156
            }
157
        }
158
159 11
        foreach ($this->map as $namespace => $prefix) {
160
161 11
            if (strpos($className, $namespace) === 0) {
162
163 11
                foreach ($this->whitelist as $whitelistedNamespace) {
164
165 1
                    if (strpos($className, $whitelistedNamespace) === 0) {
166 1
                        return $prefix.'_';
167
                    }
168
                }
169
170 11
                return 0 === count($this->whitelist) ? $prefix.'_' : '';
171
            }
172
        }
173
174 3
        return '';
175
    }
176
177
    /**
178
     * Build underscore version of given string.
179
     *
180
     * @param string $string
181
     * @return string
182
     */
183 18 View Code Duplication
    protected function underscore($string)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
184
    {
185 18
        $string = preg_replace('/(?<=[a-z])([A-Z])/', '_$1', $string);
186
187 18
        if (CASE_UPPER === $this->case) {
188 6
            return strtoupper($string);
189
        }
190
191 12
        return strtolower($string);
192
    }
193
}
194