Failed Conditions
Pull Request — 1.0 (#79)
by Bernhard
02:44
created

OptimizedJsonRepository   A

Complexity

Total Complexity 23

Size/Duplication

Total Lines 152
Duplicated Lines 26.32 %

Coupling/Cohesion

Components 1
Dependencies 4

Test Coverage

Coverage 91.3%

Importance

Changes 4
Bugs 0 Features 0
Metric Value
wmc 23
c 4
b 0
f 0
lcom 1
cbo 4
dl 40
loc 152
ccs 63
cts 69
cp 0.913
rs 10

7 Methods

Rating   Name   Duplication   Size   Complexity  
A insertReference() 0 4 1
A removeReferences() 0 12 2
B getReferencesForPath() 9 25 5
A getReferencesForGlob() 12 12 2
D getReferencesForRegex() 9 45 9
A getReferencesInDirectory() 10 10 1
A addFilesystemResource() 0 14 3

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

1
<?php
2
3
/*
4
 * This file is part of the puli/repository package.
5
 *
6
 * (c) Bernhard Schussek <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Puli\Repository;
13
14
use Puli\Repository\Api\EditableRepository;
15
use Puli\Repository\Api\Resource\FilesystemResource;
16
use Webmozart\Glob\Glob;
17
use Webmozart\PathUtil\Path;
18
19
/**
20
 * An optimized path mapping resource repository.
21
 * When a resource is added, all its children are resolved
22
 * and getting them is much faster.
23
 *
24
 * Resources can be added with the method {@link add()}:
25
 *
26
 * ```php
27
 * use Puli\Repository\OptimizedJsonRepository;
28
 *
29
 * $repo = new OptimizedJsonRepository();
30
 * $repo->add('/css', new DirectoryResource('/path/to/project/res/css'));
31
 * ```
32
 *
33
 * This repository only supports instances of FilesystemResource.
34
 *
35
 * @since  1.0
36
 *
37
 * @author Bernhard Schussek <[email protected]>
38
 * @author Titouan Galopin <[email protected]>
39
 */
40
class OptimizedJsonRepository extends AbstractJsonRepository implements EditableRepository
41
{
42
    /**
43
     * {@inheritdoc}
44
     */
45 76
    protected function insertReference($path, $reference)
46
    {
47 76
        $this->json[$path] = $reference;
48 76
    }
49
50
    /**
51
     * {@inheritdoc}
52
     */
53 7
    protected function removeReferences($glob)
54
    {
55 7
        $removed = 0;
56
57 7
        foreach ($this->getReferencesForGlob($glob.'{,/**/*}') as $path => $reference) {
58 7
            ++$removed;
59
60 7
            unset($this->json[$path]);
61 7
        }
62
63 7
        return $removed;
64
    }
65
66
    /**
67
     * {@inheritdoc}
68
     */
69 52
    protected function getReferencesForPath($path)
70
    {
71 52
        if (!array_key_exists($path, $this->json)) {
72 13
            return array();
73
        }
74
75 48
        $reference = $this->json[$path];
76
77
        // We're only interested in the first entry of eventual arrays
78 48
        if (is_array($reference)) {
79
            $reference = reset($reference);
80
        }
81
82 48 View Code Duplication
        if ($this->isFilesystemReference($reference)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
83 47
            $reference = Path::makeAbsolute($reference, $this->baseDirectory);
84
85
            // Ignore non-existing files. Not sure this is the right
86
            // thing to do.
87 47
            if (!file_exists($reference)) {
88
                return array();
89
            }
90 47
        }
91
92 48
        return array($path => $reference);
93
    }
94
95
    /**
96
     * {@inheritdoc}
97
     */
98 22 View Code Duplication
    protected function getReferencesForGlob($glob, $stopOnFirst = false)
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...
99
    {
100 22
        if (!Glob::isDynamic($glob)) {
101 16
            return $this->getReferencesForPath($glob);
102
        }
103
104 13
        return $this->getReferencesForRegex(
105 13
            Glob::getStaticPrefix($glob),
106 13
            Glob::toRegEx($glob),
107
            $stopOnFirst
108 13
        );
109
    }
110
111
    /**
112
     * {@inheritdoc}
113
     */
114 38
    protected function getReferencesForRegex($staticPrefix, $regex, $stopOnFirst = false)
115 38
    {
116 25
        $result = array();
117 25
        $foundMappingsWithPrefix = false;
118
119 25
        foreach ($this->json as $path => $reference) {
120 25
            if (0 === strpos($path, $staticPrefix)) {
121 21
                $foundMappingsWithPrefix = true;
122
123 21
                if (preg_match($regex, $path)) {
124
                    // We're only interested in the first entry of eventual arrays
125 20
                    if (is_array($reference)) {
126
                        $reference = reset($reference);
127
                    }
128
129 20 View Code Duplication
                    if ($this->isFilesystemReference($reference)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
130 20
                        $reference = Path::makeAbsolute($reference, $this->baseDirectory);
131
132
                        // Ignore non-existing files. Not sure this is the right
133
                        // thing to do.
134 20
                        if (!file_exists($reference)) {
135
                            continue;
136
                        }
137 20
                    }
138
139 20
                    $result[$path] = $reference;
140
141 20
                    if ($stopOnFirst) {
142 4
                        return $result;
143
                    }
144 17
                }
145
146 19
                continue;
147
            }
148
149
            // We did not find anything but previously found mappings with the
150
            // static prefix
151
            // The mappings are sorted alphabetically, so we can safely abort
152 21
            if ($foundMappingsWithPrefix) {
153 15
                break;
154
            }
155 24
        }
156
157 24
        return $result;
158
    }
159
160
    /**
161
     * {@inheritdoc}
162
     */
163 11 View Code Duplication
    protected function getReferencesInDirectory($path, $stopOnFirst = false)
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...
164
    {
165 11
        $basePath = rtrim($path, '/');
166
167 11
        return $this->getReferencesForRegex(
168 11
            $basePath.'/',
169 11
            '~^'.preg_quote($basePath, '~').'/[^/]+$~',
170
            $stopOnFirst
171 11
        );
172
    }
173
174
    /**
175
     * {@inheritdoc}
176
     */
177 76
    protected function addFilesystemResource($path, FilesystemResource $resource)
178
    {
179
        // Read children before attaching the resource to this repository
180 76
        $children = $resource->listChildren();
181
182 76
        parent::addFilesystemResource($path, $resource);
183
184
        // Recursively add all child resources
185 76
        $basePath = '/' === $path ? $path : $path.'/';
186
187 76
        foreach ($children as $name => $child) {
188 38
            $this->addFilesystemResource($basePath.$name, $child);
189 76
        }
190 76
    }
191
}
192