Builder   B
last analyzed

Complexity

Total Complexity 43

Size/Duplication

Total Lines 243
Duplicated Lines 0 %

Test Coverage

Coverage 77.23%

Importance

Changes 0
Metric Value
eloc 97
dl 0
loc 243
ccs 78
cts 101
cp 0.7723
rs 8.96
c 0
b 0
f 0
wmc 43

9 Methods

Rating   Name   Duplication   Size   Complexity  
A removeSortingInformations() 0 8 2
B build() 0 34 8
A createContent() 0 36 5
A getName() 0 10 2
B isIgnored() 0 17 8
B getOrCreatePage() 0 34 8
A sortTree() 0 5 3
A finalizeTree() 0 16 5
A getOrCreateDir() 0 12 2

How to fix   Complexity   

Complex Class

Complex classes like Builder often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Builder, and based on these observations, apply Extract Interface, too.

1
<?php namespace Todaymade\Daux\Tree;
2
3
use RuntimeException;
4
use SplFileInfo;
5
use Todaymade\Daux\DauxHelper;
6
7
class Builder
8
{
9
    protected static $IGNORED = [
10
        // Popular VCS Systems
11
        '.svn', '_svn', 'CVS', '_darcs', '.arch-params', '.monotone', '.bzr', '.git', '.hg',
12
13
        // Operating system files
14
        '.DS_Store', 'Thumbs.db',
15
    ];
16
17 17
    protected static function isIgnored(\SplFileInfo $file, $ignore)
18
    {
19 17
        $filename = $file->getFilename();
20
21 17
        if (in_array($filename, static::$IGNORED)) {
22
            return true;
23
        }
24
25 17
        if (array_key_exists('folders', $ignore) && $file->isDir() && in_array($filename, $ignore['folders'])) {
26
            return true;
27
        }
28
29 17
        if (array_key_exists('files', $ignore) && !$file->isDir() && in_array($filename, $ignore['files'])) {
30
            return true;
31
        }
32
33 17
        return false;
34
    }
35
36
    /**
37
     * Get name for a file
38
     *
39
     * @param string $path
40
     * @return string
41
     */
42 21
    protected static function getName($path)
43
    {
44
        // ['dir' => 1, 'basename' => 2, 'filename' => 3, 'extension' => 5]
45 21
        preg_match('%^(.*?)[\\\\/]*(([^/\\\\]*?)(\.([^\.\\\\/]+?)|))[\\\\/\.]*$%im', $path, $m);
46
47 21
        if (!isset($m[3])) {
48
            throw new RuntimeException('Name not found');
49
        }
50
51 21
        return $m[3];
52
    }
53
54
    /**
55
     * Build the initial tree
56
     *
57
     * @param Directory $node
58
     * @param array $ignore
59
     */
60 17
    public static function build($node, $ignore)
61
    {
62 17
        if (($it = new \FilesystemIterator($node->getPath())) == false) {
0 ignored issues
show
introduced by Stéphane Goetz
The condition $it = new FilesystemIter...de->getPath()) == false is always false.
Loading history...
63
            return;
64
        }
65
66 17
        if ($node instanceof Root) {
67
            // Ignore config.json in the root directory
68 17
            $ignore['files'][] = 'config.json';
69
        }
70
71
        /** @var \SplFileInfo $file */
72 17
        foreach ($it as $file) {
73 17
            if (static::isIgnored($file, $ignore)) {
74
                continue;
75
            }
76
77 17
            if ($file->isDir()) {
78 16
                $title = static::removeSortingInformations($file->getFilename());
79 16
                $new = new Directory($node, $title, $file);
80 16
                $new->setName(static::getName($file->getPathName()));
81 16
                $new->setTitle(str_replace('_', ' ', static::removeSortingInformations($new->getName())));
82 16
                static::build($new, $ignore);
83
84 16
                $index = $new->getLocalIndexPage();
85 16
                if ($index && $index->getTitle() != $title) {
86 16
                    $new->setTitle($index->getTitle());
87
                }
88
            } else {
89 17
                static::createContent($node, $file);
90
            }
91
        }
92
93 17
        $node->sort();
94 17
    }
95
96
    /**
97
     * @param Directory $parent
98
     * @param SplFileInfo $file
99
     * @return Content|Raw
100
     */
101 17
    public static function createContent(Directory $parent, SplFileInfo $file)
102
    {
103 17
        $name = static::getName($file->getPathname());
104
105 17
        $config = $parent->getConfig();
106
107 17
        if (!in_array($file->getExtension(), $config['valid_content_extensions'])) {
108 1
            $uri = $file->getFilename();
109
110 1
            $entry = new Raw($parent, $uri, $file);
111 1
            $entry->setTitle(str_replace('_', ' ', static::removeSortingInformations($name)));
112 1
            $entry->setName($name);
113
114 1
            return $entry;
115
        }
116
117 17
        $uri = static::removeSortingInformations($name);
118 17
        if ($config->isStatic()) {
119 17
            $uri .= '.html';
120
        }
121
122 17
        $entry = new Content($parent, $uri, $file);
123
124 17
        if ($entry->getUri() == $config['index_key']) {
125 1
            if ($parent instanceof Root) {
126
                $entry->setTitle($config->getTitle());
127
            } else {
128 1
                $entry->setTitle($parent->getTitle());
129
            }
130
        } else {
131 17
            $entry->setTitle(str_replace('_', ' ', static::removeSortingInformations($name)));
132
        }
133
134 17
        $entry->setName($name);
135
136 17
        return $entry;
137
    }
138
139
    /**
140
     * @param string $filename
141
     * @return string
142
     */
143 41
    public static function removeSortingInformations($filename)
144
    {
145 41
        preg_match('/^[-+]?[0-9]*_?(.*)/', $filename, $matches);
146
147
        // Remove the numeric part
148
        // of the filename, only if
149
        // there is something after
150 41
        return empty($matches[1]) ? $matches[0] : $matches[1];
151
    }
152
153
    /**
154
     * @param Directory $parent
155
     * @param string $title
156
     * @return Directory
157
     */
158 2
    public static function getOrCreateDir(Directory $parent, $title)
159
    {
160 2
        $slug = DauxHelper::slug($title);
161
162 2
        if (array_key_exists($slug, $parent->getEntries())) {
163 1
            return $parent->getEntries()[$slug];
164
        }
165
166 1
        $dir = new Directory($parent, $slug);
167 1
        $dir->setTitle($title);
168
169 1
        return $dir;
170
    }
171
172
    /**
173
     * @param Directory $parent
174
     * @param string $path
175
     * @return ContentAbstract
176
     */
177 5
    public static function getOrCreatePage(Directory $parent, $path)
178
    {
179 5
        $extension = pathinfo($path, PATHINFO_EXTENSION);
180
        // If the file doesn't have an extension, set .md as a default
181 5
        if ($extension == '') {
182 1
            $extension = 'md';
183 1
            $path .= '.md';
184
        }
185
186 5
        $raw = !in_array($extension, $parent->getConfig()['valid_content_extensions']);
187
188 5
        $title = $uri = $path;
189 5
        if (!$raw) {
190 4
            $title = static::getName($path);
191 4
            $uri = DauxHelper::slug($title);
192 4
            if ($parent->getConfig()->isStatic()) {
193 4
                $uri .= '.html';
194
            }
195
        }
196
197 5
        if (array_key_exists($uri, $parent->getEntries())) {
198 1
            return $parent->getEntries()[$uri];
199
        }
200
201 4
        $page = $raw ? new ComputedRaw($parent, $uri) : new Content($parent, $uri);
202 4
        $page->setContent('-'); //set an almost empty content to avoid problems
203 4
        $page->setName($path);
204 4
        $page->setTitle($title);
205
206 4
        if ($title == 'index' || $title == '_index') {
207 1
            $page->setTitle($parent->getTitle());
208
        }
209
210 4
        return $page;
211
    }
212
213
    /**
214
     * Sort the tree recursively
215
     *
216
     * @param Directory $current
217
     */
218
    public static function sortTree(Directory $current) {
219
        $current->sort();
220
        foreach ($current->getEntries() as $entry) {
221
            if ($entry instanceof Directory) {
222
                Builder::sortTree($entry);
223
            }
224
        }
225
    }
226
227
    /**
228
     * Calculate next and previous for all pages
229
     *
230
     * @param Directory $current
231
     * @param null|Content $prev
232
     * @return null|Content
233
     */
234
    public static function finalizeTree(Directory $current, $prev = null)
235
    {
236
        foreach ($current->getEntries() as $entry) {
237
            if ($entry instanceof Directory) {
238
                $prev = Builder::finalizeTree($entry, $prev);
239
            } elseif ($entry instanceof Content) {
240
                if ($prev) {
241
                    $prev->setNext($entry);
242
                    $entry->setPrevious($prev);
243
                }
244
245
                $prev = $entry;
246
            }
247
        }
248
249
        return $prev;
250
    }
251
252
}
253