Failed Conditions
Pull Request — 1.0 (#79)
by Bernhard
04:22 queued 01:32
created

OptimizedJsonRepository::getReferencesForRegex()   D

Complexity

Conditions 9
Paths 12

Size

Total Lines 45
Code Lines 20

Duplication

Lines 9
Ratio 20 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 9
loc 45
rs 4.9091
cc 9
eloc 20
nc 12
nop 3
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
    protected function insertReference($path, $reference)
46
    {
47
        $this->json[$path] = $reference;
48
    }
49
50
    /**
51
     * {@inheritdoc}
52
     */
53
    protected function removeReferences($glob)
54
    {
55
        $removed = 0;
56
57
        foreach ($this->getReferencesForGlob($glob.'{,/**/*}') as $path => $reference) {
58
            ++$removed;
59
60
            unset($this->json[$path]);
61
        }
62
63
        return $removed;
64
    }
65
66
    /**
67
     * {@inheritdoc}
68
     */
69
    protected function getReferencesForPath($path)
70
    {
71
        if (!array_key_exists($path, $this->json)) {
72
            return array();
73
        }
74
75
        $reference = $this->json[$path];
76
77
        // We're only interested in the first entry of eventual arrays
78
        if (is_array($reference)) {
79
            $reference = reset($reference);
80
        }
81
82 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
            $reference = Path::makeAbsolute($reference, $this->baseDirectory);
84
85
            // Ignore non-existing files. Not sure this is the right
86
            // thing to do.
87
            if (!file_exists($reference)) {
88
                return array();
89
            }
90
        }
91
92
        return array($path => $reference);
93
    }
94
95
    /**
96
     * {@inheritdoc}
97
     */
98 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
        if (!Glob::isDynamic($glob)) {
101
            return $this->getReferencesForPath($glob);
102
        }
103
104
        return $this->getReferencesForRegex(
105
            Glob::getStaticPrefix($glob),
106
            Glob::toRegEx($glob),
107
            $stopOnFirst
108
        );
109
    }
110
111
    /**
112
     * {@inheritdoc}
113
     */
114
    protected function getReferencesForRegex($staticPrefix, $regex, $stopOnFirst = false)
115
    {
116
        $result = array();
117
        $foundMappingsWithPrefix = false;
118
119
        foreach ($this->json as $path => $reference) {
120
            if (0 === strpos($path, $staticPrefix)) {
121
                $foundMappingsWithPrefix = true;
122
123
                if (preg_match($regex, $path)) {
124
                    // We're only interested in the first entry of eventual arrays
125
                    if (is_array($reference)) {
126
                        $reference = reset($reference);
127
                    }
128
129 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
                        $reference = Path::makeAbsolute($reference, $this->baseDirectory);
131
132
                        // Ignore non-existing files. Not sure this is the right
133
                        // thing to do.
134
                        if (!file_exists($reference)) {
135
                            continue;
136
                        }
137
                    }
138
139
                    $result[$path] = $reference;
140
141
                    if ($stopOnFirst) {
142
                        return $result;
143
                    }
144
                }
145
146
                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
            if ($foundMappingsWithPrefix) {
153
                break;
154
            }
155
        }
156
157
        return $result;
158
    }
159
160
    /**
161
     * {@inheritdoc}
162
     */
163 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
        $basePath = rtrim($path, '/');
166
167
        return $this->getReferencesForRegex(
168
            $basePath.'/',
169
            '~^'.preg_quote($basePath, '~').'/[^/]+$~',
170
            $stopOnFirst
171
        );
172
    }
173
174
    /**
175
     * {@inheritdoc}
176
     */
177
    protected function addFilesystemResource($path, FilesystemResource $resource)
178
    {
179
        // Read children before attaching the resource to this repository
180
        $children = $resource->listChildren();
181
182
        parent::addFilesystemResource($path, $resource);
183
184
        // Recursively add all child resources
185
        $basePath = '/' === $path ? $path : $path.'/';
186
187
        foreach ($children as $name => $child) {
188
            $this->addFilesystemResource($basePath.$name, $child);
189
        }
190
    }
191
}
192