Completed
Branch feature/currentUserRefactoring (e6f778)
by Schlaefer
02:47
created

TreeBuilder::_sortTreesAfterTime()   A

Complexity

Conditions 4
Paths 6

Size

Total Lines 17

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
nc 6
nop 2
dl 0
loc 17
rs 9.7
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
/**
6
 * Saito - The Threaded Web Forum
7
 *
8
 * @copyright Copyright (c) the Saito Project Developers
9
 * @link https://github.com/Schlaefer/Saito
10
 * @license http://opensource.org/licenses/MIT
11
 */
12
13
namespace Saito\Posting;
14
15
class TreeBuilder
16
{
17
    /**
18
     * build tree
19
     *
20
     * @param array $postings postings
21
     * @return array
22
     */
23
    public function build($postings)
24
    {
25
        $tree = [];
26
        foreach ($postings as $posting) {
27
            $id = $posting['id'];
28
            $pid = $posting['pid'];
29
            $tree[$id] = isset($tree[$id]) ? $tree[$id] + $posting : $posting;
30
            $tree[$pid]['_children'][] = &$tree[$id];
31
        }
32
33
        // both boil down to 'first entry in $tree array', but let's be clear what
34
        // is expected in $tree
35
        if (isset($tree[0])) {
36
            // $postings had root entry/-ies with $pid = 0
37
            $tree = $tree[0]['_children'];
38
        } else {
39
            // $postings are subtree: assume lowest $id is root for subtree
40
            $tree = [reset($tree)];
41
        }
42
43
        // It's possible to do uasort before tree build and  get the same results,
44
        // without _sortTreesAfterTime
45
        // but then *all* entries have to be sorted whereas now only subthreads with childs
46
        // are sorted. So using _sortTreesAfterTime is actually faster in praxis.
47
        $_sortedTrees = $this->_sortTreesAfterTime($tree);
48
49
        return $_sortedTrees;
50
    }
51
52
    /**
53
     * Sort all entries in trees after time
54
     *
55
     * @param array $in array with trees
56
     * @param int $level level
57
     * @return array
58
     */
59
    protected function _sortTreesAfterTime($in, $level = 0)
60
    {
61
        if ($level > 0) {
62
            uasort($in, [$this, '_sort']);
63
        }
64
65
        foreach ($in as $k => $v) {
66
            if (isset($v['_children'])) {
67
                $in[$k]['_children'] = $this->_sortTreesAfterTime(
68
                    $v['_children'],
69
                    $level + 1
70
                );
71
            }
72
        }
73
74
        return $in;
75
    }
76
77
    /**
78
     * Sorter
79
     *
80
     * @param array $a a
81
     * @param array $b b
82
     * @return int
83
     */
84
    protected function _sort($a, $b)
85
    {
86
        if ($a['time'] === $b['time']) {
87
            return ($a['id'] > $b['id']) ? 1 : -1;
88
        } else {
89
            return ($a['time'] > $b['time']) ? 1 : -1;
90
        }
91
    }
92
}
93