Builder   B
last analyzed

Complexity

Total Complexity 43

Size/Duplication

Total Lines 244
Duplicated Lines 0 %

Test Coverage

Coverage 77.45%

Importance

Changes 7
Bugs 1 Features 0
Metric Value
eloc 98
c 7
b 1
f 0
dl 0
loc 244
ccs 79
cts 102
cp 0.7745
rs 8.96
wmc 43

9 Methods

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